#include<iostream>
using namespace std;
const int MAXV=2000; //最大顶点数量
const int MAXE=2000; //最大边数量
const int INFINITY = 0x7fffffff; //无穷大
int capacity[MAXV][MAXV]; //记录残流网络的容量
int flow[MAXV]; //标记从源点到当前节点实际还剩多少流量可用
int pre[MAXV]; //标记在这条路径上当前节点的前驱,同时标记该节点是否在队列中
int Queue[MAXV]; //求最短增广路算法需要用到的队列
int MaxFlow(int src, int des, int n);
int Edmonds_Karp(int src, int des, int n);
int main()
{
int m, n, u, v;
printf("请输入顶点数量:");
scanf("%d", &n);
printf("\n请输入边数量:");
scanf("%d", &m);
for(int i=0; i<m; ++i)
{
cin >> u >> v;
cin >> capacity[u][v];
}
cout << MaxFlow(0, n-1, n) << endl;
system("pause");
return 0;
}
int MaxFlow(int src, int des, int n)
{
int sumFlow = 0; //存储 src到des的最大流
int inc = 0; //存储最短增广路的流量增量
int u, v;
while (inc=Edmonds_Karp(src, des, n) != -1)
{
//逆向调整增广路(即修改对应残流网络的容量)
v = des;
while (v != src)
{
u = pre[v];
capacity[u][v] -= inc;
capacity[v][u] += inc;
v = u;
}
sumFlow += inc;
}
return sumFlow;
}
int Edmonds_Karp(int src, int des, int n)//广度优先搜索寻找最短增广路
{
int u, front = 0, rear = 0; //清空队列
for(int i=0; i<n; ++i) //初始化列表
{
pre[i] = -1;
}
//源点加入队列
flow[src] = INFINITY;
pre[src] = src;
Queue[rear++] = src;
while (front < rear) //队列非空
{
u = Queue[front++];
for(int i=0; i<n; ++i) //寻找未访问过的邻接点,并计算最小增加流量
{
if (pre[i] == -1 && capacity[u][i])
{
pre[i] = u;
flow[i] = (flow[u] < capacity[u][i]) ? flow[u] : capacity[u][i];
if (i == des) //找到汇点,直接返回最小增加流量
{
return flow[des];
}
Queue[rear++] = i;
}
}
}
//判断残流网络中是否存在增广路径
return (pre[des] == -1) ? -1 : flow[des];
}
最大网络流Edmond-Karp算法
最新推荐文章于 2021-03-16 19:37:07 发布