Edmonds-Karp算法_网络流_最大流问题

可行流:即多条弧的集合,且每条弧的流量为非负的,且不超过该弧的容量;流入原点的流量等于流出终点的流量。

最大流:即网络中的流量最大的可行流。

最大流的求法:即由原网络得到残量网络,再找到残量网络中的增广路,根据增广路求最大流。

步骤:

     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

*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值