UVA - 11090 - Going in Cycle!!(二分+差分约束系统)

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

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

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 }

 

转载于:https://www.cnblogs.com/npugen/p/10762855.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值