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 }

 

posted @ 2021-04-03 23:33  jrltx  阅读(71)  评论(0编辑  收藏  举报