链接:点击打开链接
题意:给出一个有向图,问其中哪一个环的每条边的权值和除以边数最小
代码:
#include <queue> #include <vector> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <iostream> #include <algorithm> const double INF=0x3f3f3f3f; int n,m; double d[55]; struct node{ int from,to; double cost; }G[2500]; bool judge(double v){ int i,j; memset(d,0,sizeof(d)); for(i=0;i<m;i++) G[i].cost-=v; for(i=0;i<n;i++){ for(j=0;j<m;j++){ node e=G[j]; if(d[e.to]>d[e.from]+e.cost){ d[e.to]=d[e.from]+e.cost; if(i==n-1) return 1; } } } return 0; } //判断是否有负环 int main(){ double l,r,mid; int t,k,i,j; scanf("%d",&t); for(k=1;k<=t;k++){ scanf("%d%d",&n,&m); for(i=0;i<m;i++) scanf("%d%d%lf",&G[i].from,&G[i].to,&G[i].cost); if(judge(INF)==0){ //先判断是否会形成环 printf("Case #%d: No cycle found.\n",k); continue; } for(j=0;j<m;j++) G[j].cost+=INF; l=0,r=INF; for(i=0;i<100;i++){ //二分答案,最后一定会有一个答案 mid=(l+r)/2; //使得某一个环值为0 if(judge(mid)) r=mid; else l=mid; for(j=0;j<m;j++) G[j].cost+=mid; } printf("Case #%d: %.2lf\n",k,l); } return 0; }