Digression: Recent similar to retire, retire back to the semi-finals kick careful reading literacy class.
Questions surface: P2868 [USACO07DEC] sightseeing Sightseeing Cows Cows
Solution: the optimal ratio of ring
The actual subject is a requirement ans, such that for any one ring satisfying FIG sig (i = 1, n) v [i] / sig (i = 1, n) e [i] <= ans
Therefore, the formula is converted into: sig (i = 1, n) v [i] - [(sig (i = 1, n) v [i]) * ans] <= 0
sig(i=1,n)(v[i]-ans*e[i])<=0
Final into: sig (i = 1, n) (ans * e [i] -v [i])> = 0, i.e. ans * e [i] -v [i] to a new right side in FIG reconstructed, FIG respect to any one of the rings can satisfy this condition shall ans
Therefore binary answer, for each reconstructed FIG mid, SPFA a recursive loop negative judgment, if the sig (i = 1, n) (mid * e [i] -v [i]) <0 then the mid <ans, or DESCRIPTION mid> = ans
Code:
1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 const int maxn=1050,maxm=5050,inf=(1<<30)-5; 5 const double jd=1e-3; 6 int N,M,num_edge=0,edge_head[maxn],u,v; 7 double V[maxn],e,l,r,mid,Dis[maxn]; 8 bool vis[maxn],flag; 9 struct Edge{ int to,nx;double e,dis; }edge[maxm]; 10 inline void Add_edge(int from,int to,double e){ 11 edge[++num_edge].nx=edge_head[from]; 12 edge[num_edge].to=to; 13 edge[num_edge].e=e; 14 edge_head[from]=num_edge; 15 return; 16 } 17 inline void Rebuild(){ 18 for(int i=1;i<=N;i++) 19 for(int j=edge_head[i];j;j=edge[j].nx) 20 edge[j].dis=edge[j].e*mid-V[edge[j].to]; 21 return; 22 } 23 inline void SPFA(int x){ 24 if(flag) return; 25 vis[x]=1; 26 for(int i=edge_head[x];i;i=edge[i].nx){ 27 int y=edge[i].to; 28 if(Dis[y]>Dis[x]+edge[i].dis){ 29 if(vis[y]){ 30 flag=1; 31 return; 32 } 33 Dis[y]=Dis[x]+edge[i].dis; 34 SPFA(y); 35 } 36 } 37 vis[x]=0; 38 } 39 inline bool Check(){ 40 for(int i=1;i<=N;i++) vis[i]=0,Dis[i]=0; 41 flag=0; 42 for(int i=1;i<=N;i++){ 43 SPFA(i); 44 if(flag) break; 45 } 46 return flag; 47 } 48 int main(){ 49 scanf("%d%d",&N,&M); 50 for(int i=1;i<=N;i++) scanf("%lf",&V[i]); 51 for(int i=1;i<=M;i++){ 52 scanf("%d%d%lf",&u,&v,&e); 53 Add_edge(u,v,e); 54 } 55 l=0; r=10000; 56 while(l+jd<r){ 57 mid=(l+r)/2; 58 Rebuild(); 59 if(Check()) l=mid; 60 else r=mid; 61 } 62 printf("%.2lf\n",l); 63 return 0; 64 }
By:AlenaNuna