二分答案+dfs判有没有负环,这样dfs比spfa快多了。
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<queue> 7 #include<algorithm> 8 #include<vector> 9 #define M 2000009 10 #define EPS 1e-10 11 #define ll long long 12 using namespace std; 13 ll read() 14 { 15 char ch=getchar(); 16 ll x=0,f=1; 17 for(;ch<'0'||ch>'9';ch=getchar()) 18 if(ch=='-') 19 f=-1; 20 for(;ch>='0'&&ch<='9';ch=getchar()) 21 x=x*10+ch-'0'; 22 return x*f; 23 } 24 int cnt,n,m,head[M],next[M],u[M]; 25 double ans,v[M],l=0x7fffffff,r=-0x7fffffff,d[M]; 26 bool f[M]; 27 void jia(int a1,int a2,double a3) 28 { 29 cnt++; 30 next[cnt]=head[a1]; 31 head[a1]=cnt; 32 u[cnt]=a2; 33 v[cnt]=a3; 34 } 35 bool dfs(int x) 36 { 37 f[x]=1; 38 for(int i=head[x];i;i=next[i]) 39 if(d[u[i]]>d[x]+v[i]) 40 { 41 if(f[u[i]]) 42 return 1; 43 d[u[i]]=d[x]+v[i]; 44 if(dfs(u[i])) 45 return 1; 46 } 47 f[x]=0; 48 return 0; 49 } 50 bool pa() 51 { 52 for(int i=1;i<=n;i++) 53 if(dfs(i)) 54 return 1; 55 return 0; 56 } 57 bool pan(double x) 58 { 59 memset(d,0,sizeof(d)); 60 memset(f,0,sizeof(f)); 61 for(int i=1;i<=n;i++) 62 for(int j=head[i];j;j=next[j]) 63 v[j]-=x; 64 bool an=pa(); 65 for(int i=1;i<=n;i++) 66 for(int j=head[i];j;j=next[j]) 67 v[j]+=x; 68 return an; 69 } 70 int main() 71 { 72 n=read(); 73 m=read(); 74 for(int i=1;i<=m;i++) 75 { 76 int a1=read(),a2=read(); 77 double a3; 78 scanf("%lf",&a3); 79 jia(a1,a2,a3); 80 l=min(l,a3); 81 r=max(r,a3); 82 } 83 for(;r-l>1e-9;) 84 { 85 double mid=(l+r)/2; 86 if(pan(mid)) 87 { 88 r=mid; 89 ans=mid; 90 } 91 else 92 l=mid; 93 } 94 printf("%.8lf ",ans); 95 return 0; 96 }