uva11090 Bellman-Ford 运用
2015-03-17 21:30
267 查看
给定一一个n个点m条边的加权有向图, 平均值最小的回路。
二分答案,对于每个二分的mid 做一次Bellman-Fprd , 假设有k条边组成的回路。 回路上各条边的权值为 w1 , w2 ..wk ,
那么平均值小于mid意味着w1+w2+w3..+wk< k*mid 即:
(w1 - min)+(w2-mid)+...+(w2-mid)<0;
也就是说 这k条边能组成 一个负环,用 Bellman_Ford 来检查
二分答案,对于每个二分的mid 做一次Bellman-Fprd , 假设有k条边组成的回路。 回路上各条边的权值为 w1 , w2 ..wk ,
那么平均值小于mid意味着w1+w2+w3..+wk< k*mid 即:
(w1 - min)+(w2-mid)+...+(w2-mid)<0;
也就是说 这k条边能组成 一个负环,用 Bellman_Ford 来检查
#include <iostream> #include <cstdio> #include <algorithm> #include <string.h> #include <vector> #include <queue> #include <cmath> using namespace std; const int maxn = 55; int cmp(double a ,double b){ if(fabs(a-b)<=0.00000001) return 0; return a-b>0?1:-1; } struct Edge{ int from,to; double dist; }; struct BellmanFord{ int n,m; vector<Edge> edges; vector<int> G[maxn]; bool inq[maxn]; double d[maxn]; int p[maxn]; int cnt[maxn]; void inti(int n){ m=0; this->n = n; for(int i=0; i<n; ++i ) G[i].clear(); edges.clear(); } void AddEdge(int form, int to, double dist){ edges.push_back((Edge){form,to,dist}); m =edges.size(); G[form].push_back(m-1); } bool negativeCycle(){ queue<int> Q; memset(inq, 0, sizeof(inq)); memset(cnt, 0, sizeof(cnt)); for(int i=0; i < n; ++i) { d[i] =0; inq[i] = true; Q.push(i);} while(!Q.empty()){ int u = Q.front(); Q.pop(); inq[u] = false; for(int i=0; i<G[u].size(); i++){ Edge &e = edges[G[u][i]]; if(cmp(d[e.to] , d[u] + e.dist)>0){ d[e.to] = d[u] +e.dist; p[e.to] = G[u][i]; if(!inq[e.to]){ Q.push(e.to); inq[e.to] = true; if(++cnt[e.to]>n) return true; } } } } return false; } }solver; bool test(double x){ for(int i=0; i<solver.m; i++){ solver.edges[i].dist-=x; } bool ret = solver.negativeCycle(); for(int i= 0; i<solver.m; i++) solver.edges[i].dist+=x; return ret; } int main() { int T; scanf("%d",&T); for(int kase =1; kase<=T; kase++){ int n,m; scanf("%d%d",&n,&m); solver.inti(n); int ub =0; while(m--){ int u,v,w; scanf("%d%d%d",&u,&v,&w); u--,v--; ub= max(ub,w); solver.AddEdge(u,v,w); } printf("Case #%d: ",kase); double ans = ub; if(!test(ub+1)){ printf("No cycle found.\n"); }else{ double L =0,R= ub; while(R-L>1e-3){ double M = L+(R-L)/2; if(test(M)){ R=M; }else { L=M; } } printf("%.2lf\n",L); } } return 0; }
相关文章推荐
- UVa 11090 Going in Cycle!! (Bellman_Ford)
- UVA 11090 - Going in Cycle!!(Bellman-Ford)
- Bellman-Ford,最短路(在环中,UVA 11090)
- UVA 11090 Going in Cycle!!(Bellman-Ford判断负圈)
- UVa 11090 Going in Cycle!!【Bellman_Ford】
- UVA 11090 Going in Cycle!!(Bellman-Ford推断负圈)
- Uva 11090 - Going in Cycle!! bellman-ford 负权环 二分
- UVA 11090 - Going in Cycle!!(Bellman-Ford)
- Uva 11090 - Going in Cycle!! bellman-ford 负权环 二分
- UVA 11090 Going in Cycle!! 环平均权值(bellman-ford,spfa,二分)
- UVA - 558 Wormholes (Bellman-ford)
- uva_558 Wormholes (spfa 或 bellman_ford)
- UVALive 6800 The Mountain of Gold (bellman_ford判负环)
- UVa 11090 - Going in Cycle!!(正版Bellman)
- UVA 11478 Halum(用bellman-ford解差分约束)
- UVA 11090 - Going in Cycle!!(最短路`Bellman-Ford)
- UVA 10986 - Sending email(最短路 优先队列的优化+Bellman-Ford)
- uva 558 Bellman_Ford
- UVA - 11090 Going in Cycle!! (Bellman-Ford算法判负环)
- uva 558 Bellman_Ford