Dinic法求最大流

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_40924940/article/details/83480066

 经过先对图进行分层处理,我们在进行搜索的时候 就会更加的舒服了

(当然 ,代码我省略了一版,这是最终形态了。。每条路也都是用结构体实现的)

#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
 
#define MAXN 210
#define INF 0x3f3f3f3f
 
struct Edge
{
	int st, ed;//开始 结束
	int c;//权值
	int next;//下一个节点
}edge[MAXN << 1];
 
int n, m;
int s, t;
int ans;
int e = 0; 
int head[MAXN];//建立链表
int d[MAXN];//用来分层
 
void init()
{
	int a, b, c; 
	s = 1;
	t = m;
	e = 0;
	ans = 0;
	memset(head, -1, sizeof(head));
	for(int i = 1; i <= n; i++)//建立一个
	{
		scanf("%d%d%d", &a, &b, &c);
		edge[e].st = a;
		edge[e].ed = b;
		edge[e].c = c;
		edge[e].next = head[a];
		head[a] = e++;
		edge[e].st = b;
		edge[e].ed = a;
		edge[e].next = head[b];
		head[b] = e++;
	}
}
 
int bfs()
{
	memset(d, -1, sizeof(d));
	queue<int> q;
	d[s] = 0;
	q.push(s);
	int i;
	int cur;
	while(!q.empty())//BFS
	{
		cur = q.front();
		q.pop();
		for(i = head[cur]; i != -1; i = edge[i].next)
		{
			if(d[edge[i].ed] == -1 && edge[i].c > 0)
			{
				d[edge[i].ed] = d[cur] + 1; //对图进行分层处理
				q.push(edge[i].ed);
			}	
		}
	}
	if(d[t] < 0)
		return 0;
	return 1;
}
 
int dinic(int x, int flow)
{
	if(x == t)
		return flow;
	int i, a;
	for(i = head[x]; i != -1; i = edge[i].next)
	{
		if(d[edge[i].ed] == d[x] + 1 && edge[i].c > 0 && (a = dinic(edge[i].ed, min(flow, edge[i].c))))
        //首先 要确保我们在搜索时没有走“回头路” 而且可以到达终点,同时路是连通的
		{
			edge[i].c -= a;
			edge[i ^ 1].c += a;//反向增加容量 异或运算取反
			return a;	
		}
	}
	return 0;
}
 
void solve()//这段写的非常具有大牛风格
{
	while(scanf("%d%d", &n, &m) != EOF)
	{
		init();
		while(bfs())
		{
			int increment;
			increment = dinic(1, INF);
				ans +=  increment; //记录总共的流量和(即最大流量)
		}
		printf("%d\n", ans);
	}
}
 
int main()
{
	solve();
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40924940/article/details/83480066
今日推荐