2019EC-final E - Flow

One of Pang’s research interests is the maximum flow problem.

A directed graph G with n vertices is universe if the following condition is satisfied:

G is the union of k vertex-independent simple paths from vertex 1 to vertex n of the same length.
A set of paths is vertex-independent if they do not have any internal vertex in common.
A vertex in a path is called internal if it is not an endpoint of that path.

A path is simple if its vertices are distinct.

Let G be a universe graph with n vertices and m edges. Each edge has a non-negative integral capacity. You are allowed to perform the following operation any (including 0) times to make the maximum flow from vertex 1 to vertex n as large as possible:

Let e be an edge with positive capacity. Reduce the capacity of e by 1 and increase the capacity of another edge by 1.

Pang wants to know what is the minimum number of operations to achieve it?

Input
The first line contains two integers n and m (2≤n≤100000,1≤m≤200000).

Each of the next m lines contains three integers x,y and z, denoting an edge from x to y with capacity z (1≤x,y≤n, 0≤z≤1000000000).

It’s guaranteed that the input is a universe graph without multiple edges and self-loops.

Output
Output a single integer — the minimum number of operations.

Examples
inputCopy
4 3
1 2 1
2 3 2
3 4 3
outputCopy
1
inputCopy
4 4
1 2 1
1 3 1
2 4 2
3 4 2
outputCopy
1


Because the number of edges is not certain, so the total maximum flow must be constant.

We follow the flow of small to large order for each path.

For each of the first edge, if the sum is less than the flow, then there must be a big take over from the back side, otherwise you can directly break.

It is clear from behind to take to satisfy greedy.


AC Code:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10,M=N<<1;
int n,m,flow,res,cnt;
int head[N],nex[M],to[M],w[M],tot;
vector<int> v[N];
inline void add(int a,int b,int c){
	to[++tot]=b; nex[tot]=head[a]; w[tot]=c; head[a]=tot;
}
void dfs(int x){
	if(x==n)	return ;
	for(int i=head[x];i;i=nex[i]){
		v[cnt].push_back(w[i]);	dfs(to[i]);
	}
}
signed main(){
	ios::sync_with_stdio(false);	cin.tie(nullptr);
	cin>>n>>m;
	for(int i=1,a,b,c;i<=m;i++)	cin>>a>>b>>c,add(a,b,c),flow+=c;
	for(int i=head[1];i;i=nex[i]){
		v[++cnt].push_back(w[i]); dfs(to[i]);
		sort(v[cnt].begin(),v[cnt].end());
	}
	flow/=v[1].size();
	for(int i=0,s;i<v[1].size();i++){
		s=0;
		for(int j=1;j<=cnt;j++)	s+=v[j][i];
		if(s>=flow)	break;	res+=flow-s;
	}
	cout<<res;
	return 0;
}
Published 423 original articles · won praise 229 · views 10000 +

Guess you like

Origin blog.csdn.net/weixin_43826249/article/details/103948845