最大流之EK算法

本文分享了一次最大流算法的编程实践,作者通过Edmonds-Karp算法实现了一个最大流求解程序,详细介绍了从数据结构选择到算法实现的过程,并附上了完整的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

刚刚复习了最大流算法,温习了 Edmons-Karp 算法的思想和简单步骤后,第一次写的是用结构体包装节点和边,
不过后来发现这样虽然一定程度上使代码更加容易理解,但是调用变量的语句长了许多,于是还是采用数据的方式。
这样速度会快不少。以下是我写的最大流算法。发现错误或不足之处希望留言提醒更正。

#include<iostream>
#include<stdio.h>
#include<string>
#include<queue>
#include<vector>
#include<string.h>
#include<algorithm>

using namespace std;
const int maxn = 200;
const int bigint = 1e9;

int flow[maxn][maxn];	//一条边的当前流量,反向时为负数
int cap[maxn][maxn];	//一条边的最大容量
int prenode[maxn];		//用于记录到终点的路线
int potential[maxn];	//容量增加的潜力

//node munber, edge number, starting point and destination
int n, m, start, dest;

int maxflow; //answer

//初始化数值,每次BFS后都要清理potential
void clear(){
	memset(potential, 0, sizeof(potential));
	potential[start] = bigint;
}
//获取输入数据
void getdata(){
	memset(flow, 0, sizeof(flow));
	memset(cap, 0, sizeof(cap));
	cin >> n >> m >> start >> dest;
	for (int i = 0; i < m; i++){
		int from, to, val;
		cin >> from >> to >> val;
		cap[from][to] = cap[to][from] = val;
	}
	maxflow = 0;
}

int main(){
	getdata();
	queue<int>temp;
	while (true){	//不断bfs直至不能再找到增加流量的路
		clear();	//每次BFS后都要清理potential[]
		temp.push(start);
		while ( temp.empty() == false){	//bfs寻找增广路
			int nowat = temp.front();
			temp.pop();
			for (int i = 0; i < n; i++){	//每个点只访问一次,每次访问后更新其流量潜力,放到队列
				if (potential[i] == 0 && flow[nowat][i] < cap[nowat][i]){
					potential[i] = min(potential[nowat], cap[nowat][i] - flow[nowat][i]);
					prenode[i] = nowat;
					temp.push(i);
				}
			}
		}
		if (potential[dest] == 0) break;	//说明了已经找不到去终点的流,退出
		for (int u = dest; u != start; u = prenode[u]){	//进入下一次bfs前先更新当前流量,
			int l = prenode[u];
			flow[u][l] -= potential[dest];
			flow[l][u] += potential[dest];
		}
		maxflow += potential[dest];
	}
	cout << maxflow << endl;
	return 0;
}

/*
input example:
  4 4 0 3
  0 1 5
  0 2 20
  2 3 10
  1 3 100

  output : 15
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值