UVA - 11090 Going in Cycle!! (有向图平均值最小环,分数规划)
题意:求有向图平均值最小环
看到平均值就想到分数规划问题,解法是二分答案,假设存在一个平均值小于等于x的环,那么把每条边的权值减去x,然后判断是否存在负环即可。Floyed就可以判负环,spfa也行
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef double db; 5 const int N=100+10,inf=0x3f3f3f3f; 6 int n,m,ka; 7 db g[N][N],buf[N][N]; 8 bool ok(db x) { 9 for(int i=1; i<=n; ++i) 10 for(int j=1; j<=n; ++j) 11 g[i][j]=buf[i][j]-x; 12 for(int k=1; k<=n; ++k) 13 for(int i=1; i<=n; ++i) 14 for(int j=1; j<=n; ++j) 15 g[i][j]=min(g[i][j],g[i][k]+g[k][j]); 16 for(int i=1; i<=n; ++i)if(g[i][i]<=0)return 1; 17 return 0; 18 } 19 db bi(db l,db r) { 20 for(int i=0; i<50; ++i) { 21 db mid=(l+r)/2; 22 ok(mid)?r=mid:l=mid; 23 } 24 return l; 25 } 26 27 int main() { 28 int _; 29 for(scanf("%d",&_); _--;) { 30 printf("Case #%d: ",++ka); 31 scanf("%d%d",&n,&m); 32 for(int i=1; i<=n; ++i)for(int j=1; j<=n; ++j)g[i][j]=inf; 33 while(m--) { 34 int u,v; 35 db c; 36 scanf("%d%d%lf",&u,&v,&c); 37 g[u][v]=min(g[u][v],c); 38 } 39 for(int i=1; i<=n; ++i)for(int j=1; j<=n; ++j)buf[i][j]=g[i][j]; 40 db ans=bi(0,inf); 41 if(ans>1e8)puts("No cycle found."); 42 else printf("%.2f\n",ans); 43 } 44 return 0; 45 }