可行流:即多条弧的集合,且每条弧的流量为非负的,且不超过该弧的容量;流入原点的流量等于流出终点的流量。
最大流:即网络中的流量最大的可行流。
最大流的求法:即由原网络得到残量网络,再找到残量网络中的增广路,根据增广路求最大流。
步骤:
1. 找到残量网络中的一条增广路。
2. 求出该增广路上的最小的流量值,使各个弧的容量都减去这个值,并各个反向弧都加上这个值。
3. 重复1,2 直到找不到增广路。将每一次的流量值相加,结果为最大流。
图中的最大流 为 S->T: 10
代码如下:
#include <iostream>
#include <queue>
#include <memory.h>
#define INF 0x7FFFFFFF
#define MAX 100
using namespace std;
int map[MAX][MAX];
int path[MAX];
/*---------------深度优先遍历*/
int bfs(int n , int start , int end)
{
queue <int> q;
int flow[n];
memset(path , -1 , sizeof(path));
path[start] = 0 , flow[start] = INF;
q.push(start);
int i , t;
while(! q.empty()){
t = q.front();
q.pop();
if(t == end) break;
for(i = 1 ; i <= n ; i++){
if(i != start && path[i] == -1 && map[t][i]){
flow[i] = flow[t] < map[t][i] ? flow[t]:map[t][i];//---获取最小剩余容量
q.push(i);
path[i] = t;
}
}
}
if(path[end] == -1) return -1;
return flow[n];//----返回路径上最小剩余容量的弧
}
/*-------------Edmonds_Karp 算法*/
int Edmonds_Karp(int n , int start , int end)
{
int max_flow = 0 , step , now , pre;
while((step = bfs(n , start , end)) != -1){//----能获取到达end的路径
max_flow += step;//---最大容量++
now = end;
while(now != start){
pre = path[now];
map[pre][now] -= step;//----剩余容量
map[now][pre] += step;//----已使用容量
now = pre;
}
}
return max_flow;
}
/*----------main()*/
int main()
{
int m , n;
cin>>m>>n;
memset(map , 0 , sizeof(map));
int u , v , cost;
for(int i = 0 ; i < m ; i++){
cin>>u>>v>>cost;
map[u][v] += cost;
}
int start = 1 , end = n;
cout<<"max_flow:\t"<<Edmonds_Karp(n , start , end)<<endl;
return 0;
}
/*
Sample Input
5 4
1 2 40
1 4 20
2 4 20
2 3 30
3 4 10
Sample Output
50
*/