网络流Edmond-Karp算法

本文详细介绍了网络流中的Edmond-Karp算法,包括其基础概念、思想及应用实例。通过具体代码实现,读者可以更好地掌握如何在残留网络中寻找增广路,并计算最大流量。

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

前阵子都在忙PHP的事,没有时间去更新博客,今天下午终于狠下心来学网络流,在这里讲一下网络流Edmond-Karp算法的基础内容。
至于网络流的一些基础概念,这里就不说明了,大家可以去百度或看书。
其思想是不断通过BFS寻找一条增广路,直到残留网络中不再存在增广路为止。
对于每次找到一条增广路,我们需要知道两条信息。
1、该增广路的最大流量(可以定义一个变量来求得)。
2、该增广路的路径(可以定义一个数组来存每个节点的前驱)。
对于每次增广,从 x 到 y 的容量减少增广流量的同时从 y 到 x 的容量也要增加增广的流量。

找了这么一题来练手:POJ1273 代码如下:
#include <set>
#include <map>
#include <list>
#include <stack>
#include <queue>
#include <cmath>
#include <cstdio>
#include <vector>
#include <iomanip>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;

#define pi 3.1415926535897932385
#define LL64 __int64
#define LL long long
#define N 210
#define M 2147483647

int n, m;//m个点,n条边
int arr[N][N];//记录残留网络的容量
int pre[N];//记录前驱
int flow[N];//记录当前最大流量

int bfs(int source, int sink)
{
queue<int> q;
while (!q.empty())
{
q.pop();
}
memset(pre, -1, sizeof(pre));
pre[source] = 0;
flow[source] = M;
q.push(source);
while (!q.empty())
{
int index = q.front();
if (index == sink) break;//找到了增广路径
q.pop();
for (int i = 2; i <= m; i++)
{
if (arr[index][i] <= 0 || pre[i] != -1) continue;
pre[i] = index;//记录前驱
flow[i] = min(arr[index][i], flow[index]);//记录当前最大流量
q.push(i);
}
}
if (pre[sink] == -1) return -1;//残留图中不再存在增广路径
return flow[sink];
}

int maxflow(int source, int sink)
{
int flow_sum = 0;
int inc = 0;
while ((inc = bfs(source, sink)) != -1)
{
int s = sink;
while (s != source)
{
int p = pre[s];
arr[p][s] -= inc;
arr[s][p] += inc;
s = p;
}
flow_sum += inc;
}
return flow_sum;
}

int main()
{
//freopen("data.in", "r", stdin);
//freopen("data.out", "w", stdout);

while (~scanf("%d%d", &n, &m))
{
memset(arr, 0, sizeof(arr));
for (int i = 0; i < n; i++)
{
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
if (x == y) continue;
arr[x][y] += z;
}
printf("%d\n", maxflow(1, m));
}

return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值