网络流Edmond-Karp算法

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

找了这么一题来练手:POJ1273 代码如下:
#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
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 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;
}

你可能感兴趣的:(ACM算法)