01分数规划
二分+spfa负环(SLF优化)
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; int n,m; double p[1100]; struct edge{int x,y;double d;}e[5100]; struct node { int x,y,next;double d; }a[11000];int len,last[1100]; void ins(int x,int y,double d) { len++; a[len].x=x;a[len].y=y;a[len].d=d; a[len].next=last[x];last[x]=len; } double d[1100]; int list[1100000],inq[1100]; bool v[1100]; bool check(double mid) { len=0;memset(last,0,sizeof(last)); for(int i=1;i<=m;i++) ins(e[i].x,e[i].y,mid*e[i].d-p[e[i].x]); memset(d,0,sizeof(0)); memset(v,true,sizeof(v)); memset(inq,0,sizeof(inq)); int head=500000,tail=500000; for(int i=1;i<=n;i++)list[tail++]=i; while(head!=tail) { int x=list[head];head++; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(d[y]>d[x]+a[k].d) { d[y]=d[x]+a[k].d; inq[y]++;if(inq[y]==n)return true; if(v[y]==false) { v[y]=true; if(d[y]>d[list[head]])list[tail++]=y; else list[--head]=y; } } } v[x]=false; } return false; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%lf",&p[i]); for(int i=1;i<=m;i++) scanf("%d%d%lf",&e[i].x,&e[i].y,&e[i].d); double l=0,r=100000.0; while(r-l>1e-5) { double mid=(l+r)/2; if(check(mid))l=mid; else r=mid; } printf("%.2lf ",l); return 0; }