Description
Input
Output
Sample Input
4 5
1 2 5
2 3 5
3 1 5
2 4 3
4 1 3
Sample Output
3.66666667
题解:
01分数规划。。就是用来求两个Σ的比值用的,建立关系后跑最短路即可,具体可参见代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int MAXN=10001;
const int INF=1e9;
struct xx
{
int to,nxt;
double w;
}e[MAXN];
int head[MAXN];
double dist[MAXN],w[MAXN];
int u[MAXN],v[MAXN];
int cnt,n,E;
bool flag;
bool visit[MAXN];
void add(int x,int y,double z)
{
cnt++;
e[cnt].to=y;
e[cnt].nxt=head[x];
e[cnt].w=z;
head[x]=cnt;
}
void dfs(int x)
{
int i;
visit[x]=1;
for(i=head[x];i;i=e[i].nxt)
{
if(dist[e[i].to]>dist[x]+e[i].w)
{
if(visit[e[i].to])
{flag=1;break;}
else {
dist[e[i].to]=dist[x]+e[i].w;
dfs(e[i].to);
}
}
}
visit[x]=0;
}
bool check(double x)
{
int i;
memset(head,0,sizeof(head));
memset(dist,0,sizeof(dist));
memset(visit,0,sizeof(visit));
cnt=0;
for(i=1;i<=E;i++)
add(u[i],v[i],w[i]-x);
flag=0;
for(i=1;i<=n;i++)
{
dfs(i);
if(flag) return 1;
}
return 0;
}
int main(int argc, char *argv[])
{
int i,j;
scanf("%d%d",&n,&E);
for(i=1;i<=E;i++)
scanf("%d%d%lf",&u[i],&v[i],&w[i]);
double l,r,mid;
l=-INF,r=INF;
while(l<r-0.000000001)
{
mid=(l+r)*1.0/2*1.0;
if(check(mid)) r=mid;
else l=mid;
}printf("%.8f\n",l);
return 0;
}