B. Minimum Average Path ###K //K
题目链接:https://codeforces.ml/edu/course/2/lesson/6/4/practice/status
题意:给定一张有向图 问1到n 权值的平均值 最小的 路径是哪条
思路: 二分check 平均值 把每条边 减去平均值得到贡献
最终1~n 距离小于0的 即为合法 因为有负边权的最短路 所以掏出spfa冲过去
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define ull unsigned long long 5 #define pb push_back 6 #define pi pair<int,double> 7 #define fi first 8 #define sc second 9 10 const int maxn=1e5+10; 11 const int mod=1e9+7; 12 13 vector<pi>E[maxn]; 14 double d[maxn]; 15 int st[maxn]; 16 int n,m; 17 18 struct ac 19 { 20 int u,v,w; 21 }; 22 ac a[maxn]; 23 vector<int>ans; 24 int pre[maxn]; 25 26 bool check(double x) 27 { 28 for(int i=1;i<=n;i++) 29 { 30 st[i]=0; 31 E[i].clear(); 32 d[i]=1e9; 33 } 34 for(int i=1;i<=m;i++) 35 { 36 int u=a[i].u,v=a[i].v,w=a[i].w; 37 double y=w-x; 38 E[u].pb({v,y}); 39 } 40 41 queue<int>q; 42 st[1]=1; 43 q.push(1); 44 d[1]=0; 45 46 while(!q.empty()) 47 { 48 int u=q.front(); 49 q.pop(); 50 st[u]=0; 51 52 for(auto &v:E[u]) 53 { 54 if(d[v.fi]>d[u]+v.sc) 55 { 56 pre[v.fi]=u; 57 d[v.fi]=d[u]+v.sc; 58 if(st[v.fi]) continue; 59 q.push(v.fi); 60 st[v.fi]=1; 61 } 62 } 63 } 64 65 if(d[n]<=0) 66 { 67 int k=n; 68 vector<int>cnt; 69 pre[0]=-1; 70 while(pre[k]!=-1) 71 { 72 cnt.pb(k); 73 k=pre[k]; 74 } 75 ans=cnt; 76 return 1; 77 } 78 return 0; 79 } 80 81 82 83 int main() 84 { 85 ios::sync_with_stdio(0); 86 cin.tie(0); 87 cin>>n>>m; 88 for(int i=1;i<=m;i++) 89 { 90 int u,v,w; 91 cin>>u>>v>>w; 92 a[i]={u,v,w}; 93 } 94 double l=0,r=100; 95 for(int i=0;i<100;i++) 96 { 97 double mid=(l+r)/2; 98 if(check(mid)) r=mid; 99 else l=mid; 100 } 101 reverse(ans.begin(),ans.end()); 102 int len=ans.size(); 103 cout<<len-1<<'\n'; 104 for(int i=0;i<len;i++) 105 { 106 if(i!=0) cout<<" "; 107 cout<<ans[i]; 108 } 109 110 111 112 113 114 115 116 117 }

浙公网安备 33010602011771号