首页 > 代码库 > uva 11090

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 }
View Code