UVA 11090 Going in Cycle!! SPFA判断负环+二分
2017-03-08 20:49
603 查看
题目链接:
https://vjudge.net/problem/UVA-11090题意:
给你一个有向图,问你定义一个环的平均值为这个环上所有边的平均值,问你最小的环的平均值是多少题解:
二分答案:若当前的二分值是mid,让所有的边都减去这个值,如果此时图中出现负环,则说明有环的平均值比这个更小假设一个包含k条边的回路,回路上各条边的权值为w1,w2……wk,那么平均值小于mid意味着 w1+w2+……wk< k* mid即:
(w1-mid)+(w2-mid)+……(wk-mid)<0
有负环,当前平均值就大了
注意图可能不连通,每个没访问过得点都spfa判一遍
代码:
#include <bits/stdc++.h> using namespace std; typedef long long ll; #define MS(a) memset(a,0,sizeof(a)) #define MP make_pair #define PB push_back const int INF = 0x3f3f3f3f; const ll INFLL = 0x3f3f3f3f3f3f3f3fLL; inline ll read(){ ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } ////////////////////////////////////////////////////////////////////////// const int maxn = 50+10; double eps = 1e-6; int n,m; vector<pair<int,double> > G[maxn]; int vis[maxn],inq[maxn],cnt[maxn]; double d[maxn]; bool spfa(int u){ MS(inq);MS(cnt); for(int i=0; i<=n; i++) d[i] = INF; queue<int> q; q.push(u),inq[u]=1,d[u]=0; while(!q.empty()){ int now = q.front(); q.pop(); inq[now] = 0; vis[now] = 1; for(int i=0; i<(int)G[now].size(); i++){ int v = G[now][i].first; double w = G[now][i].second; if(d[v] > d[now]+w){ d[v] = d[now]+w; if(inq[v]) continue; inq[v] = 1; q.push(v); cnt[v]++; if(cnt[v] > n) return true; } } } return false; } bool check(double x){ for(int i=1; i<=n; i++) for(int j=0; j<(int)G[i].size(); j++) G[i][j].second -= x; // 让所有的边都减去mid,如果此时图中出现负环,则说明有环的平均值比这个更小 MS(vis); bool flag; for(int i=1; i<=n; i++){ if(!vis[i]) // 图可能不连通,每个没访问过得点都判一遍 flag = spfa(i); if(flag) break; } for(int i=1; i<=n; i++) for(int j=0; j<(int)G[i].size(); j++) G[i][j].second += x; return flag; // flag为true 就是有负环,当前平均值就大了 } int main(){ int T = read(); for(int cas=1; cas<=T; cas++){ for (int i = 0; i <= n; i++)G[i].clear(); scanf("%d%d",&n,&m); for(int i=1; i<=m; i++){ int u,v; double w; scanf("%d%d%lf",&u,&v,&w); G[u].push_back(MP(v,w)); } double L=0,R=1e7,ans=1e7; while((R-L)>eps){ double mid = (L+R)/2; if(check(mid)) ans=mid,R=mid-eps; else L=mid+eps; } if(abs(ans-1e7)<eps) printf("Case #%d: No cycle found.\n",cas); else printf("Case #%d: %.2lf\n",cas,ans); } return 0; }
相关文章推荐
- UVA 11090 Going in Cycle!! SPFA判断负环+二分
- UVA11090 Going in Cycle!! 解题报告【判负环】【SPFA】【二分答案】
- UVA11090 Going in Cycle!! (二分+SPFA判断有无负权)
- UVA 11090 Going in Cycle!!(二分 + spfa 判负环)
- UVA11090 Going in Cycle!! (二分+SPFA推断有无负权)
- UVA11090 Going in Cycle (二分+判负环)
- UVA 11090 : Going in Cycle!! (SPFA+二分)
- UVA 11090 Going in Cycle!! (spfa + 二分)
- UVA 11090 Going in Cycle!! 环平均权值(bellman-ford,spfa,二分)
- UVa 11090 Going in Cycle!!(环上平均值最大+SPFA DFS判负环)
- UVA 11090 Going in Cycle!!——二分+spfa
- UVA 11090 Going in Cycle!!(二分 + spfa)
- UVA 11090 Going in Cycle!!(Bellman-Ford判断负圈)
- uva 11090 - Going in Cycle!!(二分+BellmanFord)
- Uva 11090 - Going in Cycle!! bellman-ford 负权环 二分
- Uva 11090 Going in Cycle!!(二分+最短路)
- UVA 11090 - Going in Cycle!! SPFA
- UVA-11090 - Going in Cycle!!(BellmanFord判负环)
- UVA 11090 - Going in Cycle!! SPFA
- Uva 11090 - Going in Cycle!! bellman-ford 负权环 二分