【UVA2031】cycle {二分+spfa/Bellman ford}
2016-10-30 00:12
316 查看
【题目描述】
给定一个有n个顶点m条边的加权有向图,如果图中存在环(回路),环的平均值等于,环上边的权值之和除以构成环的边数,图中可能不止存在一个回路,计算平均权值最小的回路。
【Sample Input】
(输入第一行为数据组数T(t<=10),每组数据第一行为图的点数n和边数m(n<=50).以下m行3个正整数u,v,w,表示有一条从u到v的有向边,权值为w,输入没有自环。)
2
2 1
1 2 1
2 2
1 2 2
2 1 3
【Sample Output】
(对于每组数据输出最小平均值,保留两位小数。如果无解,输出“No cycle found.” 每组数据输出格式如下(x表示第几组数据): Case #x:最小平均值或 No cycle found.)
Case #1: No cycle found.
Case #2: 2.50
【数据范围】
T<=10;n ≤ 50,m<=n*n;u, v ≤ n;w ≤ 10000000
【题解】二分+spfa或bellman ford判负环
本题要求最小平均环。直接搜索显然会超时(大概搜索拿了30)。在很难直接确定答案的情况下,考虑用二分来做。
二分之后我们有了可能的答案mid。考虑如果答案可行,即某个环的平均值小于等于此可能解,设这个环上的边劝为w[1]至w[k],则可以得到:
w[1]+w[2]+…+w[k]<=k*mid
→ (w[1]-mid)+(w[2]-mid)+…+(w[k]-mid)<=0
故而我们将所有边的权值减去mid,判断图内是否存在负环,若有则最小平均值<=当前答案。如果无论二分值多大都无法得到负环,则证明此图无环。
给定一个有n个顶点m条边的加权有向图,如果图中存在环(回路),环的平均值等于,环上边的权值之和除以构成环的边数,图中可能不止存在一个回路,计算平均权值最小的回路。
【Sample Input】
(输入第一行为数据组数T(t<=10),每组数据第一行为图的点数n和边数m(n<=50).以下m行3个正整数u,v,w,表示有一条从u到v的有向边,权值为w,输入没有自环。)
2
2 1
1 2 1
2 2
1 2 2
2 1 3
【Sample Output】
(对于每组数据输出最小平均值,保留两位小数。如果无解,输出“No cycle found.” 每组数据输出格式如下(x表示第几组数据): Case #x:最小平均值或 No cycle found.)
Case #1: No cycle found.
Case #2: 2.50
【数据范围】
T<=10;n ≤ 50,m<=n*n;u, v ≤ n;w ≤ 10000000
【题解】二分+spfa或bellman ford判负环
本题要求最小平均环。直接搜索显然会超时(大概搜索拿了30)。在很难直接确定答案的情况下,考虑用二分来做。
二分之后我们有了可能的答案mid。考虑如果答案可行,即某个环的平均值小于等于此可能解,设这个环上的边劝为w[1]至w[k],则可以得到:
w[1]+w[2]+…+w[k]<=k*mid
→ (w[1]-mid)+(w[2]-mid)+…+(w[k]-mid)<=0
故而我们将所有边的权值减去mid,判断图内是否存在负环,若有则最小平均值<=当前答案。如果无论二分值多大都无法得到负环,则证明此图无环。
#include <cstdio> #include <iostream> #include <cstring> #define N 55 #define inf 1000000000 int n,m,T,u[N*N],v[N*N],w[N*N]; double dis ,ans; bool work(double x) { for (int i=1;i<=n;++i) dis[i]=0; bool bo; for (int i=1;i<=n;++i) { bo=false; for (int j=1;j<=m;++j) if (dis[v[j]]>dis[u[j]]+w[j]-x) dis[v[j]]=dis[u[j]]+w[j]-x,bo=true; if (!bo) return false; } return true; } int main() { int cas=1; for (scanf("%d\n",&T);T--;++cas) { printf("Case #%d: ",cas); scanf("%d%d\n",&n,&m); for (int i=1;i<=m;++i) scanf("%d%d%d\n",&u[i],&v[i],&w[i]); double l=0,r=1e8; ans=-1.0; for (;l+1e-6<r;) { double mid=0.5*(l+r); if (work(mid)) r=mid,ans=mid; else l=mid; } if (ans<0) printf("No cycle found.\n"); else printf("%.2f\n",ans); } return 0; }
相关文章推荐
- UVA 11090 Going in Cycle!! 环平均权值(bellman-ford,spfa,二分)
- Uva 11090 - Going in Cycle!! bellman-ford 负权环 二分
- Uva 11090 - Going in Cycle!! bellman-ford 负权环 二分
- UVA 11090 Going in Cycle!!——二分+spfa
- UVA11090 Going in Cycle!! (二分+SPFA推断有无负权)
- UVa 558 Wormholes 判断负权环 对比bellman-ford和spfa效率
- UVA 11090 Going in Cycle!!(Bellman-Ford判断负圈)
- UVA 10000 -Longest Paths-Bellman - Ford,flody,spfa
- UVA 11090 - Going in Cycle!!(Bellman-Ford)
- UVA 11090 Going in Cycle!! SPFA判断负环+二分
- UVA 11090 Going in Cycle!!(二分 + spfa 判负环)
- UVa 11090 Going in Cycle!!【Bellman_Ford】
- UVA 11090 Going in Cycle!! SPFA判断负环+二分
- UVA 11090 - Going in Cycle!!(Bellman-Ford)
- UVA 11090 : Going in Cycle!! (SPFA+二分)
- UVA 11090 Going in Cycle!! (spfa + 二分)
- uva_558 Wormholes (spfa 或 bellman_ford)
- UVa 11090 Going in Cycle!! (Bellman_Ford)
- UVA11090 Going in Cycle!! 解题报告【判负环】【SPFA】【二分答案】
- UVA 11090 Going in Cycle!!(二分 + spfa)