欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

E - Flow Gym - 102471E

发布时间:2023/12/3 49 豆豆
生活随笔 收集整理的这篇文章主要介绍了 E - Flow Gym - 102471E 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

E - Flow Gym - 102471E

题意:

n个点,m条边,从点1到点n有k条相同长度的路径,每个边都有对应的容量,你可以进行任意次操作,每次将一个边的容量-1,将另一个边的容量+1,问最少操作多少次可以使得跑最大流的结果最大

题解:

很容易发现我们可以直接计算出最大流的最大值,因为我们有所有边的容量,极端操作我们可以将所有边的容量全部分配到一条路上,也就是最大流的最大值sum=所有流量综合一条路径的长度sum=\frac{所有流量综合}{一条路径的长度}sum=
如果我们不操作,当前的最大流答案为每条路径的最小值之和,不过当前这个最大流的答案要比理想的sum小,我们如何通过操作提升到sum?
刚才分析得出,最大流的结果和每一条路径的最小值有关,那我们就每次操作提升最小值即可。我们将每一条道路上的边按照容量排序(每条路之间彼此独立,没有影响),然后每一条路径的最小容量之和,就是当前最大流sum1,sum减sum1就是我们要补的量(也就是操作次数),补完后我们开始考虑每一条路径的次小值,之和sum2就是当前最新的网络流,与sum的差距就是再次要补的量。这样一直操作,直到最新的网络流容量大于等于sum
你可能要问我们知道被补的,那谁是被扣除的呢?其实不用管,因为我们已经求了sum,也就是总有操作可以使得最大流到sum,我们每次补可以认为是容量大的一些边均摊减,我们不需要知道具体的操作方案,只需要知道操作的影响和结果即可

代码:

#include <bits/stdc++.h> #include <unordered_map> #define debug(a, b) printf("%s = %d\n", a, b); using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> PII; clock_t startTime, endTime; //Fe~Jozky const ll INF_ll= 1e18; const int INF_int= 0x3f3f3f3f; void read(){}; template <typename _Tp, typename... _Tps> void read(_Tp& x, _Tps&... Ar) {x= 0;char c= getchar();bool flag= 0;while (c < '0' || c > '9')flag|= (c == '-'), c= getchar();while (c >= '0' && c <= '9')x= (x << 3) + (x << 1) + (c ^ 48), c= getchar();if (flag)x= -x;read(Ar...); } template <typename T> inline void write(T x) {if (x < 0) {x= ~(x - 1);putchar('-');}if (x > 9)write(x / 10);putchar(x % 10 + '0'); } void rd_test() { #ifdef ONLINE_JUDGE #elsestartTime = clock ();freopen("data.in", "r", stdin); #endif } void Time_test() { #ifdef ONLINE_JUDGE #elseendTime= clock();printf("\nRun Time:%lfs\n", (double)(endTime - startTime) / CLOCKS_PER_SEC); #endif } const int maxn=2e5+9; vector<pair<int,ll> >vec[maxn]; vector<ll>v[maxn]; ll ans=0; int main() {//rd_test();int n,m;read(n,m);ll tot=0;for(int i=1;i<=m;i++){int x,y,w;read(x,y,w);vec[x].push_back({y,w});tot+=w;}int cnt=0;for(int i=0;i<vec[1].size();i++){cnt++;int tmp=vec[1][i].first;v[cnt].push_back(vec[1][i].second);while(tmp!=n){v[cnt].push_back(vec[tmp][0].second);tmp=vec[tmp][0].first;}}for(int i=1;i<=cnt;i++){sort(v[i].begin(),v[i].end());}ll k=m/cnt;ll ave=tot/k;for(int i=0;i<k;i++){ll sum=0;for(int j=1;j<=cnt;j++)sum+=v[j][i];ans+=max(0ll,ave-sum);}cout<<ans<<endl;//Time_test(); }

总结

以上是生活随笔为你收集整理的E - Flow Gym - 102471E的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。