【Luogu】P3288方伯伯运椰子(消圈定理)
分数规划题,详见luogu题解
#include<cstdio> #include<cstring> #include<cctype> #include<algorithm> #include<cstdlib> #include<cmath> #define maxn 100010 #define eps 1e-9 using namespace std; inline long long read(){ long long num=0,f=1; char ch=getchar(); while(!isdigit(ch)){ if(ch=='-') f=-1; ch=getchar(); } while(isdigit(ch)){ num=num*10+ch-'0'; ch=getchar(); } return num*f; } struct Edge{ int next,to;double val; }edge[maxn*2]; int head[maxn],num; inline void add(int from,int to,double val){ edge[++num]=(Edge){head[from],to,val}; head[from]=num; } bool vis[maxn]; double dis[maxn]; bool spfa(int x,double mid){ vis[x]=1; for(int i=head[x];i;i=edge[i].next){ int to=edge[i].to; if(dis[to]<=dis[x]+edge[i].val+mid) continue; dis[to]=dis[x]+edge[i].val+mid; if(vis[to]) return 1; if(spfa(to,mid)) return 1; } vis[x]=0; return 0; } int n,m; bool check(double mid){ memset(dis,0,sizeof(dis)); memset(vis,0,sizeof(vis)); for(int i=1;i<=n;++i) if(spfa(i,mid)) return 1; return 0; } int main(){ n=read()+2,m=read(); for(int i=1;i<=m;++i){ int from=read(),to=read(),a=read(),b=read(),c=read(),d=read(); if(c!=0) add(to,from,a-d); add(from,to,b+d); } double l=0,r=0x7fffffff,ans=0; while(fabs(r-l)>eps){ double mid=(l+r)/2.0; if(check(mid)){ ans=mid; l=mid; } else r=mid; } printf("%.2lf",ans); return 0; }