2019EC-FINAL E题 Flow(贪心)
这题的图非常特殊,首先他没有交点,其次他每条路径的长度都是相等的,也就是每一条边都是对应的。
根据常规的贪心思路,因为他的最大流是全部路径中的流量和,并且你将一个边-1,必有另一个边+1,最大流的答案就是总容量/路径上的边数
那么其实可以想出做法了,我们已经知道的最大流是多少,所以我们将路径按权值排序,对应路径上的容量全部相加,因为每条路都会收到容量小的边的控制,所以一定要贯通这些边,使得他们的和大于最大流。
只需要判断最大流是否大于当前容量和即可。
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=5e5+10; int h[N],ne[N],e[N],w[N],idx; vector<int> g[N]; int n,m,cnt; void add(int a,int b,int c){ e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++; } void dfs(int u,int fa){ if(u==n) return ; int i; for(i=h[u];i!=-1;i=ne[i]){ int j=e[i]; if(j==fa) continue; g[cnt].push_back(w[i]); dfs(j,u); } } int main(){ ios::sync_with_stdio(false); memset(h,-1,sizeof h); int i; cin>>n>>m; ll flow=0; for(i=1;i<=m;i++){ int x,y,z; cin>>x>>y>>z; add(x,y,z); flow+=z; } for(i=h[1];i!=-1;i=ne[i]){ int j=e[i]; g[++cnt].push_back(w[i]); dfs(j,-1); sort(g[cnt].begin(),g[cnt].end()); } flow/=(int)g[1].size(); ll ans=0; for(i=0;i<(int)g[1].size();i++){ ll sum=0; for(int j=1;j<=cnt;j++){ sum+=g[j][i]; } if(sum>=flow) break; ans+=(flow-sum); } cout<<ans<<endl; }
没有人不辛苦,只有人不喊疼