Analysis
最优比例路径,二分一个答案,用所有路径长度减去这个二分出来的答案,找一条长度为0的最短路
小数和精度的问题可以用乘一个很大的数解决
嗯,某中题库封掉了我的帐号
Code
#include <stdio.h>
#include <queue>
#define N 401
#define M 4001
#define F 10000
#define INF 0x7f7f7f7f
using namespace std;
struct edge{int y,w,next;}e[M];
int dis[N],ls[M],maxE=0;
bool vis[N];
void add(int x,int y,int w){e[++maxE]=(edge){y,w,ls[x]};ls[x]=maxE;}
int spfa(int st,int ed,int p)
{
for (int i=0;i<N;i++)dis[i]=INF;
queue<int>q;
q.push(st);
vis[st]=true;
dis[st]=0;
while (!q.empty())
{
int now=q.front();q.pop();
for (int i=ls[now];i;i=e[i].next)
if (e[i].w+dis[now]-p<dis[e[i].y])
{
dis[e[i].y]=dis[now]+e[i].w-p;
if (!vis[e[i].y])
{
vis[e[i].y]=true;
q.push(e[i].y);
}
}
vis[now]=false;
}
return dis[ed];
}
int main()
{
freopen("calabash.in","r",stdin);
freopen("calabash.out","w",stdout);
int n,m;
scanf("%d%d",&n,&m);
for (int i=1;i<=m;i++)
{
int x,y,w;
scanf("%d%d%d",&x,&y,&w);
add(x,y,w*F);
}
add(0,1,0);
int x=0,y=n;
int l=0,r=INF;
bool flag=false;
while (l<=r)
{
int mid=(l+r)>>1;
int tmp=spfa(x,y,mid);
if (tmp<0)
r=mid-1;
else
if (tmp>0)
l=mid+1;
else
break;
}
printf("%.3f\n",l/(F*1.0));
return 0;
}