计蒜客 排涝 网络流 增广路算法

版权声明:未经允许禁止转载。转载请联系我WX:yuyi5453。并且注明出处 https://blog.csdn.net/weixin_40532377/article/details/84337498

题目链接:https://nanti.jisuanke.com/t/36

一道正经的网络流题,给了你边以及最大流量,求从能到汇点的最大流量

容量:一条边最大容量

流量:一条边实际流过的量

增广路算法:

1.BFS找到一条能够到达汇点的路

2.给这条路增加容量,达到能最大能容纳的流量,这一条路的每一段 容量 = 初始流量 - 流量

3.如果还有路继续1,否则到4

4,将所有能到汇点流量求和

可以参考《算法竞赛入门经典》,自己模拟一下,很容易的。

题目代码

#include<bits/stdc++.h>
using namespace std;
#define INF 999999999
const int maxn = 205;
struct Edge{
	int from,to,cap,flow;	//容量  流量
	Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){}
};

struct EdmondsKarp{
	int n,m;
	vector<Edge> edges;        
	vector<int> G[maxn];
	int a[maxn];
	int p[maxn];
	
	void init(int n){
		for(int i=0;i<n;i++) G[i].clear();
		edges.clear();
	}
	
	void AddEdge(int from,int to,int cap){
		edges.push_back(Edge(from,to,cap,0));
		edges.push_back(Edge(to,from,0,0));
		m=edges.size();
		G[from].push_back(m-2);
		G[to].push_back(m-1); 
	}
	
	int Maxflow(int s,int t){
		int flow=0;
		for(;;){
			memset(a,0,sizeof(a));
			queue<int>Q;
			Q.push(s);
			a[s]=INF;
			while(!Q.empty()){
				int x=Q.front();Q.pop();
				for(int i=0;i<G[x].size();i++){
					Edge& e=edges[G[x][i]];
					if(!a[e.to] && e.cap>e.flow){
						p[e.to]=G[x][i];
						a[e.to]=min(a[x],e.cap-e.flow);
						Q.push(e.to);
					}
				}
				if(a[t]) break;
			}
			if(!a[t]) break;
			for(int u=t;u!=s;u=edges[p[u]].from){
				edges[p[u]].flow += a[t];
				edges[p[u]^1].flow -= a[t];
			}
			flow+=a[t];
		}
		return flow;
	}
}; 


int main()
{
	EdmondsKarp Ek;
	int n,m;
	cin>>n>>m;
	Ek.init(m);
	int from,to,cap;
	for(int i=0;i<n;i++){
		scanf("%d%d%d",&from,&to,&cap);
		Ek.AddEdge(from,to,cap);
	}
	cout<<Ek.Maxflow(1,m);
}

猜你喜欢

转载自blog.csdn.net/weixin_40532377/article/details/84337498