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 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, N. N test cases follow. Each one starts with two numbers n and m. m 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 |
Case #1: No cycle found. |
| |
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 }
原文:http://www.cnblogs.com/hyxsolitude/p/3702005.html