uva 11090



































0 6

Problem G: Going in Cycle!!

Input: standard input

Output: standard output


You are given a weighted directed graph
with n vertices
and m edges. Each cycle in the graph has a
weight, which equals to sum of its edges. There are so many cycles in the
graph with different weights. In this problem we want to find a cycle with
the minimum mean.

Input

The first line of input gives the number of
cases, NN test cases
follow. Each one starts with two
numbers n and mm lines
follow, each has three positive number a, b,
c
 which means there is an edge from
vertex a to b with
weight of c.


Output

For each test case output one line containing “Case
#x:
 ” followed by a number that is the lowest mean cycle in
graph with 2 digits after decimal place, if there is a cycle. Otherwise
print “No cycle found.”.

Constraints

-           n
≤ 50

-           a,
b ≤ n

-           c
≤ 10000000

Sample Input

Output for Sample Input

2
2 1
1 2 1
2 2
1 2 2
2 1 3

Case #1: No cycle found.
Case #2: 2.50


Problemsetter: Mohammad Tavakoli Ghinani

Alternate Solution: Cho

二分答案,判断是否有负权回路。

 1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 #include <algorithm>
5 #include <queue>
6
7 using namespace std;
8
9 const int MAX_N = 100;
10 const double eps = 1e-5;
11 const int edge = 3000;
12 int first[MAX_N],Next[edge],v[edge];
13 double w[edge];
14 bool inq[MAX_N];
15 int cnt[MAX_N];
16 double d[MAX_N];
17 int N,M;
18 double sum = 0;
19
20 void add_edge(int id,int u) {
21 int e = first[u];
22 Next[id] = e;
23 first[u] = id;
24 }
25
26 bool bellman(double x) {
27 queue<int> q;
28 memset(inq,0,sizeof(inq));
29 memset(cnt,0,sizeof(cnt));
30 for(int i = 1; i <= N; ++i) {
31 d[i] = 0;
32 inq[i] = 1;
33 q.push(i);
34 }
35
36 while(!q.empty()) {
37 int u = q.front(); q.pop();
38 inq[u] = 0;
39 for(int e = first[u]; e != -1; e = Next[e]) {
40 if(d[ v[e] ] > d[u] + w[e] - x) {
41 d[ v[e] ] = d[u] + w[e] - x;
42 if(!inq[ v[e] ]) {
43 q.push( v[e] );
44 inq[ v[e] ] = 1;
45 if(++cnt[ v[e] ] > N) return true;
46 }
47 }
48 }
49 }
50
51 return false;
52
53 }
54
55 void solve() {
56 double l = 1,r = sum;
57 while(r - l >= eps) {
58 //printf("l = %f r = %f\n",l,r);
59 double mid = (l + r) / 2;
60 if(bellman(mid)) r = mid;
61 else l = mid;
62 }
63 if(bellman(sum + 1)) {
64 printf("%.2f\n",l);
65 } else {
66 printf("No cycle found.\n");
67 }
68 }
69
70 int main()
71 {
72 //freopen("sw.in","r",stdin);
73 int t;
74 scanf("%d",&t);
75 for(int ca = 1; ca <= t; ++ca) {
76 scanf("%d%d",&N,&M);
77 for(int i = 1; i <= N; ++i) first[i] = -1;
78 sum = 0;
79 for(int i = 0; i < M; ++i) {
80 int u;
81 scanf("%d%d%lf",&u,&v[i],&w[i]);
82 sum += w[i];
83 add_edge(i,u);
84 }
85
86 //printf("sum = %f\n",sum);
87 printf("Case #%d: ",ca);
88 solve();
89 }
90 //cout << "Hello world!" << endl;
91 return 0;
92 }

时间: 2024-11-10 02:39:27

uva 11090的相关文章

UVA 11090 - Going in Cycle!!(Bellman-Ford)

UVA 11090 - Going in Cycle!! 题目链接 题意:给定一个有向图,球平均权值最小的回路 思路:二分+判负环,每次二分一个值mid,判断是否存在小于mid的环,那么就是(w1 + w2 + w3...) / n < mid == w1 - mid + w2 - mid + w3 - mid .... < 0,所以每次二分的时候,把边权值减掉mid,之后bellmanford判负环即可 代码: #include <cstdio> #include <cst

UVA 11090 判负圈问题

题目链接http://vjudge.net/problem/viewProblem.action?id=34650 题目大意: 给定n个点m条边的加权有向图,求平均权值最小的回路.平均权值=路径权值之和/路径边数 我们可以通过找到他其中的最小和最大值,然后通过二分不断查找满足的点,然后尽可能的取到它的最大值,因为这里保留两位有效小数,所以设立 while(la-st>0.001)即可 找到一个满足的值是要建立在图上的每一条线段减去这个值后便能得到一个负圈,我们通常用spfa判负圈. 这个spfa

UVA 11090 - Going in Cycle!!

二分+SPFA找负环 11090 - Going in Cycle!! Time limit: 3.000 seconds I I U P C 2 0 0 6 Problem G: Going in Cycle!! Input: standard input Output: standard output You are given a weighted directed graph with n vertices and m edges. Each cycle in the graph has

UVA - 11090 Going in Cycle!! (Bellman-Ford算法判负环)

Description I I U P C 2 0 06 Problem G: Going in Cycle!! Input: standard input Output: standard output You are given a weighted directed graph with n vertices and m edges. Each cycle in the graph has a weight, which equals to sum of its edges. There

训练指南 UVA - 11090(最短路BellmanFord+ 二分判负环)

layout: post title: 训练指南 UVA - 11090(最短路BellmanFord+ 二分判负环) author: "luowentaoaa" catalog: true mathjax: true tags: - 最短路 - 基础DP - BellmanFord - 图论 - 训练指南 Going in Cycle!! UVA - 11090 题意 就最小的环的平均权值 题解 分枚举平均值mid,只需判断是否存在平均值小于mid的回路,即判断是否有sum(wi)&

UVA 11090 Going in Cycle!!(Bellman-Ford判断负圈)

题意:给定一个n个点m条边的加权有向图,求平均权值最小的回路. 思路:使用二分法求解,对于每一个枚举值mid,判断每条边权值减去mid后有无负圈即可. #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostream> #include<algorithm> #include<vector> #include<

UVa 11090 Going in Cycle!! (Bellman_Ford)

题意:给定一个加权有向图,求平均权值最小的回路. 析:先十分答案,假设答案是 ans,那么有这么一个回路,w1+w2+w3+...+wk < k*ans,这样就是答案太大,然后移项可得,(w1-ans)+(w2-ans)+(w3-ans) + ..+(wk-ans) < 0,这样的话就判断是不是有负图就好了. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio&g

UVa 11090 Going in Cycle!!【Bellman_Ford】

题意:给出n个点m条边的加权有向图,求平均值最小的回路 自己想的是用DFS找环(真是too young),在比较找到各个环的平均权值,可是代码实现不了,觉得又不太对 后来看书= =好巧妙的办法, 使用二分法求解,首先记录下来这m条边的最大权值ub 然后可以猜测一个mid,只需要判断是否存在平均值小于mid的回路 假设存在一个包含k条边的回路,回路上各条边的权值分别为w1,w,2,w3,----,wk 那么 w1+w2+w3+----+wk<k*mid 又因为联想到Bellman_Ford可以解决

UVA 11090 Going in Cycle!! 环平均权值(bellman-ford,spfa,二分)

题意:给定一个n个点m条边的带权有向图,求平均权值最小的回路的平均权值? 思路:首先,图中得有环的存在才有解,其次再解决这个最小平均权值为多少.一般这种就是二分猜平均权值了,因为环在哪也难以找出来,还有可能是一条边属于多个环.对于每个猜到的平均值,如果对应环的存在,那么这个环的每条边的权减去这个平均值之后,用spfa算法就能判断其是否有环的存在即可. 假设环上各边权值为:w1+w2+...+wk. 式子:w1+w2+...+wk<k*even   相当于   (w1-even)+(w2-even