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


因为没条边的数量是一定的,所以总共最大流一定是一定的。

我们对每一条路径按照流量从小到大排序。

对于每一个的第一条边,如果总和小于flow,那么必然从后面大的边拿过来,否则直接break即可。

从后面拿很明显的满足贪心的。


AC代码:

#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;
}
发布了423 篇原创文章 · 获赞 229 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_43826249/article/details/103948845