Problem UVA - 11090 - Going in Cycle!!
Time Limit: 3000 mSec
Problem Description
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
Sample Output
Case #1: No cycle found.
Case #2: 2.50
题解:差分约束系统板子题,配上二分很容易解决,这里的spfa和一般的spfa稍有区别,原因我在UVA 11478的博客里解释过了,不再赘述,这种写法会比分别以每个点为源点跑高效不少,目前这份代码耗时50ms,但是分别以每个点为源点跑了200ms。
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define REP(i, n) for (int i = 1; i <= (n); i++) 6 #define sqr(x) ((x) * (x)) 7 8 const int maxn = 500 + 10; 9 const int maxm = 3000 + 10; 10 const int maxs = 10000 + 10; 11 12 typedef long long LL; 13 typedef pair<int, int> pii; 14 typedef pair<double, double> pdd; 15 16 const LL unit = 1LL; 17 const int INF = 0x3f3f3f3f; 18 const LL mod = 1000000007; 19 const double eps = 1e-14; 20 const double inf = 1e15; 21 const double pi = acos(-1.0); 22 23 struct Edge 24 { 25 int to, next; 26 double w; 27 } edge[maxm << 1]; 28 29 int n, m; 30 int tot, head[maxn]; 31 32 void init() 33 { 34 tot = 0; 35 memset(head, -1, sizeof(head)); 36 } 37 38 void AddEdge(int u, int v, double w) 39 { 40 edge[tot].to = v; 41 edge[tot].next = head[u]; 42 edge[tot].w = w; 43 head[u] = tot++; 44 } 45 46 double dist[maxn]; 47 bool vis[maxn]; 48 int cnt[maxn]; 49 50 bool spfa() 51 { 52 queue<int> que; 53 for (int i = 0; i < n; i++) 54 { 55 dist[i] = 0; 56 cnt[i] = 0; 57 vis[i] = true; 58 que.push(i); 59 } 60 61 while (!que.empty()) 62 { 63 int x = que.front(); 64 que.pop(); 65 vis[x] = false; 66 for (int i = head[x]; i != -1; i = edge[i].next) 67 { 68 int v = edge[i].to; 69 if (dist[v] > dist[x] + edge[i].w) 70 { 71 dist[v] = dist[x] + edge[i].w; 72 if (!vis[v]) 73 { 74 que.push(v); 75 vis[v] = true; 76 if (++cnt[v] > n) 77 { 78 return true; 79 } 80 } 81 } 82 } 83 } 84 return false; 85 } 86 87 bool Judge(double x) 88 { 89 for (int i = 0; i < tot; i++) 90 { 91 edge[i].w -= x; 92 } 93 bool ok = true; 94 if(spfa()) 95 ok = false; 96 for (int i = 0; i < tot; i++) 97 { 98 edge[i].w += x; 99 } 100 return ok; 101 } 102 103 int iCase; 104 105 int main() 106 { 107 ios::sync_with_stdio(false); 108 cin.tie(0); 109 //freopen("input.txt", "r", stdin); 110 //freopen("output.txt", "w", stdout); 111 int T; 112 cin >> T; 113 while (T--) 114 { 115 cin >> n >> m; 116 init(); 117 int u, v; 118 double w; 119 double lim = -inf; 120 for (int i = 0; i < m; i++) 121 { 122 cin >> u >> v >> w; 123 u--, v--; 124 AddEdge(u, v, w); 125 lim = max(lim, w); 126 } 127 cout << "Case #" << ++iCase << ": "; 128 if (Judge(lim + 1)) 129 { 130 cout << "No cycle found." << endl; 131 } 132 else 133 { 134 double le = 0, ri = lim; 135 while (ri - le > 1e-3) 136 { 137 double mid = (le + ri) / 2; 138 if (Judge(mid)) 139 { 140 le = mid; 141 } 142 else 143 { 144 ri = mid; 145 } 146 } 147 cout << fixed << setprecision(2) << le << endl; 148 } 149 } 150 return 0; 151 }