spfa+ Two-point answer
When I started, I wanted to go straight to graph theory, and later found it seemed wrong (otherwise the data range is so small)
But obviously to use the graph theory, witty I think of the two-point answer.
Consider that if there is an ans, then if there is a length i/time i >=ans (I belongs to the edge on the path), then obviously better, then you can find that the problem can be converted to if an answer is better, then for the weight of length i?ans*time I, the reconstructed diagram, If the longest road to N is not less than N, it is obvious that the answer can be better, and only two points are needed. And if there's a positive ring, it's obviously possible.
The only thing to note is that the accuracy requirements to meet the test instructions, obviously can not only be divided into the third decimal places stopped, then the GI
#include <iostream>#include<cstdio>#include<cmath>#include<cstring>#include<cstdlib>#include<algorithm>#include<queue>#include<vector>using namespacestd;Const intMAXN =101;intN;intTIM[MAXN][MAXN],S[MAXN][MAXN];Long DoubleJU[MAXN][MAXN];DoubleDIS[MAXN];BOOLVIS[MAXN];intNUM[MAXN];//record the number of times, and sentence the ringLong Doubleans;//Two-point answer +SPFAQueue<int>Q;inlineintGetint () {intw=0, q=0; CharC=GetChar (); while((c<'0'|| C>'9') && c!='-') c=GetChar (); if(c=='-') q=1, c=GetChar (); while(c>='0'&& c<='9') w=w*Ten+c-'0', c=GetChar (); returnQ? -W:w;} InlineBOOLWorkLong Doublex) {//longest running path for(intI=1; i<=n;i++) dis[i]=-0x7ffffff;//to a smaller negative value//memset (dis,0,sizeof (dis));ans=x; for(intI=1; i<=n;i++) for(intj=1; j<=n;j++) Ju[i][j]=s[i][j]-x*Tim[i][j]; memset (Vis,0,sizeof(VIS)); memset (num,0,sizeof(num)); while(!q.empty ()) Q.pop (); Q.push (1); vis[1]=1; dis[1]=0; while(!Q.empty ()) { intu=Q.front (); Q.pop (); Vis[u]=0; for(intI=1; i<=n;i++) if(i!=7) { if(dis[i]<dis[u]+Ju[u][i]) {Dis[i]=dis[u]+Ju[u][i]; if(!Vis[i]) {Vis[i]=1; Q.push (i); Num[i]++; if(num[i]>=n)return true; } } } } if(dis[n]>=0)return true;//There's a better answer. return false;}intMain () {n=Getint (); for(intI=1; i<=n;i++) for(intj=1; j<=n;j++) s[i][j]=Getint (); for(intI=1; i<=n;i++) for(intj=1; j<=n;j++) tim[i][j]=Getint (); Long DoubleL=0.00, r=10000.00; //A long double jingdu=0.00001; Long Doublejingdu=0.0001; while(r-l-jingdu>=0) { Long Doublemid=l+ (r-l)/2.0; if(Work (mid)) l=mid; ElseR=mid; } printf ("%.3LF",(Double) L); return 0;}
codevs1183 Muddy roads.