Description
对于100%的数据, n≤3000,m≤10000,∣wi,j∣≤107
Solution
写写水题
二分答案找负环即可。一开始数组开小就挂了
Code
#include <stdio.h>
#include <string.h>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
#define fill(x,t) memset(x,t,sizeof(x))
const int INF=1e8;
const int N=40005;
const int E=40005;
struct edge {int y; double w; int next;} e[E];
int x[N],y[N],n,m;
int ls[N],edCnt;
double w[N],dis[N];
bool vis[N],flag;
void add_edge(int x,int y,double w) {
e[++edCnt]=(edge) {y,w,ls[x]}; ls[x]=edCnt;
}
void spfa(int now) {
if (flag) return ;
vis[now]=1;
for (int i=ls[now];i;i=e[i].next) {
if (dis[now]+e[i].w>=dis[e[i].y]) continue;
dis[e[i].y]=dis[now]+e[i].w;
if (vis[e[i].y]) {
flag=true;
return ;
} else spfa(e[i].y);
}
vis[now]=0;
}
bool check(double mid) {
fill(ls,0); edCnt=0;
rep(i,1,m) add_edge(x[i],y[i],w[i]-mid);
fill(vis,0); fill(dis,0);
flag=false;
rep(i,1,n) {
spfa(i);
if (flag) return true;
}
return false;
}
int main(void) {
freopen("data.in","r",stdin);
scanf("%d%d",&n,&m);
rep(i,1,m) {
scanf("%d%d%lf",&x[i],&y[i],&w[i]);
}
double l=-10000000,r=10000000;
rep(i,1,60) {
double mid=(l+r)*0.5;
if (check(mid)) r=mid;
else l=mid;
}
printf("%.8lf\n", l);
return 0;
}