1. 程式人生 > >UVa 11090 Going in Cycle! BellmanFord 判負權環

UVa 11090 Going in Cycle! BellmanFord 判負權環

題目大意:
給你一個由n個點,m條邊組成的有向圖,求圖中最小環的平均長度。
分析:
根據最小環的條件,我們可以通過二分的方法來實現,對於每個當前二分出來的答案,要使得環上的每一條邊的平均值小於當前答案,就等價於

w(i,j)|(i,j)E<midsize(E)
進一步可以推匯出:
(w(i,j)|(i,j)Emid)<0
所以說,只要把每一條邊的權值減去mid再判斷新圖中是否存在負權環即可。
程式碼:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 60;

struct
Edge { int from, to; double dist; }; struct BellmanFord { int n, m; vector<Edge> edges; vector<int> G[maxn]; bool inque[maxn]; double dis[maxn]; int pre[maxn], cnt[maxn]; void init(int n) { this->n = n; for(int i=0; i<n; i++) G[i].clear(); edges.clear(); } void
AddEdge(int from, int to, double dist) { edges.push_back((Edge){from, to, dist}); m = edges.size(); G[from].push_back(m-1); } bool negativeCycle() { queue<int> q; memset(cnt, 0, sizeof(cnt)); memset(inque, false, sizeof(inque)); for
(int i=0; i<n; i++) dis[i] = 0, q.push(i), inque[i] = true; while(!q.empty()) { int u = q.front(); q.pop(); inque[u] = false; for(int i=0; i<(int)G[u].size(); i++) { Edge& e = edges[G[u][i]]; if(dis[e.to] > dis[u] + e.dist) { dis[e.to] = dis[u] + e.dist; if(!inque[e.to]) { q.push(e.to); pre[e.to] = G[u][i]; inque[e.to] = true; if(++cnt[e.to] > n) return true; } } } } return false; } }Bel; bool check(double mid) { for(int i=0; i<Bel.m; i++) Bel.edges[i].dist -= mid; bool res = Bel.negativeCycle(); for(int i=0; i<Bel.m; i++) Bel.edges[i].dist += mid; return res; } double binary_search(double L, double R) { while(R - L > 1e-5) { double M = L + (R-L)/2; if(check(M)) R = M; else L = M; } return L; } int Case, T, n, m, u, v, w; int main() { #ifndef ONLINE_JUDGE freopen("data.txt", "r", stdin); freopen("ans.txt", "w", stdout); #endif scanf("%d", &T); while(T--) { scanf("%d%d", &n, &m); Bel.init(n); double L = 0, R = 0; for(int i=0; i<m; i++) { scanf("%d%d%d", &u, &v, &w); u--, v--, R = R < w ? w : R; Bel.AddEdge(u, v, w); } printf("Case #%d: ", ++Case); if(!check(R + 1)) { printf("No cycle found.\n"); continue; } double ans = binary_search(L, R); printf("%.2f\n", ans); } return 0; }