UVa 11090 在环中

https://vjudge.net/problem/UVA-11090

题意:

给定一个n个点m条边的加权有向图,求平均权值最小的回路。

 

思路:

二分枚举,只需要把每条边的权值变为w-mid,之后判断是否存在负圈即可。

  1 #include <iostream>  
  2 #include <cstring>  
  3 #include <algorithm>   
  4 #include <vector>
  5 #include <queue>
  6 using namespace std;
  7 
  8 const int maxn = 50 + 5;
  9 
 10 int n, m;
 11 
 12 struct Edge
 13 {
 14     int from, to;
 15     double dist;
 16     Edge(int u, int v, double d) :from(u), to(v), dist(d){}
 17 };
 18 
 19 struct BellmanFord
 20 {
 21     int n, m;
 22     vector<Edge> edges;
 23     vector<int> G[maxn];
 24     bool inq[maxn];
 25     double d[maxn];
 26     int p[maxn];
 27     int cnt[maxn];
 28 
 29     void init(int n)
 30     {
 31         this->n = n;
 32         for (int i = 0; i < n; i++)
 33             G[i].clear();
 34         edges.clear();
 35     }
 36 
 37     void AddEdge(int from, int to, double dist)
 38     {
 39         edges.push_back(Edge(from, to, dist));
 40         int m = edges.size();
 41         G[from].push_back(m - 1);
 42     }
 43 
 44     bool negativeCycle()
 45     {
 46         queue<int> Q;
 47         memset(inq, 0, sizeof(inq));
 48         memset(cnt, 0, sizeof(cnt));
 49         for (int i = 0; i < n; i++)
 50         {
 51             d[i] = 0; inq[0] = true; Q.push(i); 
 52         }
 53 
 54         while (!Q.empty())
 55         {
 56             int u = Q.front();
 57             Q.pop();
 58             inq[u] = false;
 59             for (int i = 0; i < G[u].size(); i++)
 60             {
 61                 Edge& e = edges[G[u][i]];
 62                 if (d[e.to]>d[u] + e.dist)
 63                 {
 64                     d[e.to] = d[u] + e.dist;
 65                     p[e.to] = e.from;
 66                     if (!inq[e.to])
 67                     {
 68                         Q.push(e.to);
 69                         inq[e.to] = true;
 70                         if (++cnt[e.to] > n)   return true;
 71                     }
 72                 }
 73             }
 74         }
 75         return false;
 76     }
 77 }solver;
 78 
 79 bool test(double x)
 80 {
 81     for (int i = 0; i < m; i++)
 82         solver.edges[i].dist -= x;
 83     bool ret = solver.negativeCycle();
 84     for (int i = 0; i < m; i++)
 85         solver.edges[i].dist += x;
 86     return ret;
 87 }
 88 
 89 int main()
 90 {
 91     //freopen("D:\\input.txt", "r", stdin);
 92     int T;
 93     int u, v, d;
 94     scanf("%d", &T);
 95     for (int kase = 1; kase <= T; kase++)
 96     {
 97         scanf("%d%d", &n, &m);
 98         solver.init(n);
 99         int ub = 0;
100         for (int i = 0; i < m; i++)    
101         {
102             scanf("%d%d%d", &u, &v, &d);
103             ub = max(ub, d);
104             solver.AddEdge(u - 1, v - 1, d);
105         }
106         printf("Case #%d: ", kase);
107         if (!test(ub + 1))   printf("No cycle found.\n");
108         else
109         {
110             double L = 0, R = ub;
111             while (R - L > 1e-3)
112             {
113                 double M = L + (R - L) / 2;
114                 if (test(M))  R = M;
115                 else L = M;
116             }
117             printf("%.2lf\n", L);
118         }
119     }
120     return 0;
121 }

 

posted @ 2017-04-04 15:42  Kayden_Cheung  阅读(213)  评论(0编辑  收藏  举报
//目录