#include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int maxn=10000+10; const double eps=0.0001; const int nil=0x3f3f3f3f; struct my{ int next,v; double w; }; int adj[maxn],adj2[maxn],cnt[maxn],fa,fa2,n,m; double w[maxn],d[maxn]; queue<int>Q; bool inq[maxn]; my bian[maxn],bian2[maxn]; void myinsert(int u,int v,double w){ bian[++fa].v=v; bian[fa].next=adj[u]; bian[fa].w=w; adj[u]=fa; } void myinsert2(int u,int v,double w){ bian2[++fa2].v=v; bian2[fa2].next=adj2[u]; bian2[fa2].w=w; adj2[u]=fa2; } bool spfa(int s){ for (int i=1;i<=n;i++) d[i]=nil,inq[i]=0,cnt[i]=0; while(!Q.empty()) Q.pop(); Q.push(s); d[s]=0; inq[s]=true; while(!Q.empty()){ int u=Q.front();Q.pop(); inq[u]=false; for (int i=adj[u];i;i=bian[i].next){ int v=bian[i].v; if(d[u]<nil&&d[v]>d[u]+bian[i].w){ d[v]=d[u]+bian[i].w; if(!inq[v]){ inq[v]=true; Q.push(v); if(++cnt[v]>n) return false; } } } } return true; } bool check(double mid){ for (int i=1;i<=n;i++){ for (int j=adj[i];j;j=bian[j].next){ bian[j].w=bian2[j].w*mid-w[bian[j].v]; } } if(!spfa(1)) return true; return false; } int main(){ scanf("%d%d",&n,&m); for (int i=1;i<=n;i++){ scanf("%lf",&w[i]); } int u,v; double w; for (int i=1;i<=m;i++){ scanf("%d%d%lf",&u,&v,&w); myinsert(u,v,w); myinsert2(u,v,w); } double l=0,r=1000.0,mid; while(r-l>eps){ mid=(l+r)/2.0; if(check(mid)) l=mid; else r=mid; //printf("%.2lf",mid); } printf("%.2lf ",mid); return 0; }
就不用讲了吧
0-1分数规划+判断图的负环