[ICPC2019西安E] Flow - 贪心
Description
给出一个有向简单图,顶点 (1) 到顶点 (n) 之间有若干条长度相同、互不相交的路径;每条路径具有容量,一次操作可以将某条边容量减一而另一条边容量加一,问最少多少次操作后可以达到最大流量?
Solution
将每条链上的各权值升序排序,然后每条链对应位置加在一起,当作一条链处理
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 200005;
int n, m;
vector<pair<int, int>> g[N];
vector<int> a[N];
int ind;
void dfs(int p)
{
if (p != n)
{
for (auto [q, w] : g[p])
{
if (p == 1)
++ind;
a[ind].push_back(w);
dfs(q);
}
}
}
signed main()
{
ios::sync_with_stdio(false);
cin >> n >> m;
int avg = 0;
for (int i = 1; i <= m; i++)
{
int u, v, w;
cin >> u >> v >> w;
g[u].push_back({v, w});
avg += w;
}
dfs(1);
int len = a[1].size();
avg /= len;
for (int i = 1; i <= ind; i++)
sort(a[i].begin(), a[i].end());
int ans = 0;
for (int i = 0; i < len; i++)
{
int sum = 0;
for (int j = 1; j <= ind; j++)
sum += a[j][i];
if (sum < avg)
ans += avg - sum;
}
cout << ans << endl;
}