Title meaning
There is a directed graph, each point a little right, each side also has the edge right
There are cows and from any point of view, after at least two points back to square one, that is, a walking ring
After asking the right point of sigma / sigma edge weight is the largest number
Topic analysis
Initially thought out, read online say forfeit ring with SPFA also do not quite understand
Because it is not right to say that the point of each point only get it once, SPFA is how to deal with this point?
Then I think, because I was thinking the exclusion of backtrack
Because backtrack did not get right to the point, but increased the edge weight is definitely not worth
But SPFA sentence negative loop will not backtrack ah! ! ! If you return the same way, that it still rings that overlap the edge of it
So I worry about
——————————————————————
If sigmaPi / sigmaWi maximize, so any one answer ans must <= sigmaPi / sigmaWi
What is the conversion sigmaPi-sigmaWi * ans> = 0 => sigma (Pi-ans * Wi)> = 0
Then is two points if ans satisfy this equation, low = mid, or high = mid
But the sigma (Pi-ans * Wi) how demand it
Only think with SPFA, if it shows negative loop sigma edge Quanshi back to this starting point from a starting point to walk around <0
So the right side into our Pi-ans * Wi can do
Topic Code
Handwriting can be initialized too, memset will wa, do not know why ......
Metaphysics memset
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> #include<queue> using namespace std; typedef long long LL; const int maxm=5007; const int maxn=1007; const double eps=1e-7; struct edge{ int to,next,dis; }e[maxm]; int head[maxm],tot; void add(int u,int v,int w){ e[tot].dis=w; e[tot].to=v; e[tot].next=head[u]; head[u]=tot++; } int f[maxn],n,m,a,b,c; bool SPFA(double x){ double dis[maxn]; bool vis[maxn]; int num[maxn]; for(int i=1;i<=n;i++){ dis[i]=1e100; vis[i]=false; num[i]=0; } // memset(dis,1e100,sizeof(dis)); // memset(vis,false,sizeof(vis)); // memset(num,0,sizeof(num)); queue<int>q; q.push(1); dis[1]=0; vis[1]=true; num[1]++; while(!q.empty()){ int u=q.front();q.pop(); vis[u]=false; for(int i=head[u];i!=-1;i=e[i].next){ int v=e[i].to; if(dis[v]>dis[u]+x*e[i].dis-f[v]){ dis[v]=dis[u]+x*e[i].dis-f[v]; if(!vis[v]){ vis[v]=true; q.push(v); num[v]++; if(num[v]>n)return true; } } } } return false; } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&f[i]); memset(head,-1,sizeof(head)); for(int i=1;i<=m;i++){ scanf("%d%d%d",&a,&b,&c); add(a,b,c); } double l=0.0,r=10000,mid; while(r-l>eps){ mid=(l+r)/2; if(SPFA(mid))l=mid; else r=mid; } printf("%.2f\n",mid); return 0; }