Description
##题解:
看到题目很快想出来思路,但是实现起来各种问题,首先我打了弱智的spfa判负环,结果TLE,后来tkj大神教我用深搜的spfa判,结果因为我菜,还是错的一塌糊涂,后来发现是因为直接return true,没有把标记清除,我真是太菜了!
##代码:
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
const int Maxn=3010;
const int Maxm=10010;
const double inf=10000000;
struct Edge{int y,next;double d;}e[Maxm];
int last[Maxn],len=0,n,m;
void ins(int x,int y,double d)
{
int t=++len;
e[t].y=y;e[t].d=d;
e[t].next=last[x];last[x]=t;
}
double f[Maxn];
bool in[Maxn];
bool tf;
void spfa(int x,double v)
{
in[x]=true;
for(int i=last[x];i;i=e[i].next)
{
int y=e[i].y;double d=e[i].d-v;
if(f[x]+d<f[y])
{
if(!in[y])
{
f[y]=f[x]+d;
spfa(y,v);
}
else{tf=true;return;}
}
}
in[x]=false;
}
bool check(double v)
{
memset(in,false,sizeof(in));
for(int i=1;i<=n;i++)f[i]=0.0;
tf=false;
for(int i=1;i<=n;i++)
{
spfa(i,v);
if(tf)return true;
}
return false;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int x,y;double d;
scanf("%d%d%lf",&x,&y,&d);
ins(x,y,d);
}
double l=-inf,r=inf;
int c=60;
while(c--)
{
double mid=(l+r)/2.0;
if(check(mid))r=mid;
else l=mid;
}
printf("%.8lf",l);
}