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 |
二分答案,判断是否有负权回路。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue> using namespace std; const int MAX_N = ;
const double eps = 1e-;
const int edge = ;
int first[MAX_N],Next[edge],v[edge];
double w[edge];
bool inq[MAX_N];
int cnt[MAX_N];
double d[MAX_N];
int N,M;
double sum = ; void add_edge(int id,int u) {
int e = first[u];
Next[id] = e;
first[u] = id;
} bool bellman(double x) {
queue<int> q;
memset(inq,,sizeof(inq));
memset(cnt,,sizeof(cnt));
for(int i = ; i <= N; ++i) {
d[i] = ;
inq[i] = ;
q.push(i);
} while(!q.empty()) {
int u = q.front(); q.pop();
inq[u] = ;
for(int e = first[u]; e != -; e = Next[e]) {
if(d[ v[e] ] > d[u] + w[e] - x) {
d[ v[e] ] = d[u] + w[e] - x;
if(!inq[ v[e] ]) {
q.push( v[e] );
inq[ v[e] ] = ;
if(++cnt[ v[e] ] > N) return true;
}
}
}
} return false; } void solve() {
double l = ,r = sum;
while(r - l >= eps) {
//printf("l = %f r = %f\n",l,r);
double mid = (l + r) / ;
if(bellman(mid)) r = mid;
else l = mid;
}
if(bellman(sum + )) {
printf("%.2f\n",l);
} else {
printf("No cycle found.\n");
}
} int main()
{
//freopen("sw.in","r",stdin);
int t;
scanf("%d",&t);
for(int ca = ; ca <= t; ++ca) {
scanf("%d%d",&N,&M);
for(int i = ; i <= N; ++i) first[i] = -;
sum = ;
for(int i = ; i < M; ++i) {
int u;
scanf("%d%d%lf",&u,&v[i],&w[i]);
sum += w[i];
add_edge(i,u);
} //printf("sum = %f\n",sum);
printf("Case #%d: ",ca);
solve();
}
//cout << "Hello world!" << endl;
return ;
}