链接:点击打开链接
题意:给出一个有向图,问其中哪一个环的每条边的权值和除以边数最小
代码:
#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;
}