最大流EK算法

本文深入探讨了最大流问题,并重点解析了Edmonds-Karp算法(EK算法)的工作原理和实现步骤。通过实例分析,解释了如何利用EK算法寻找网络中从源点到汇点的最大传输能力,从而解决实际中的流量分配问题。
摘要由CSDN通过智能技术生成

最大流EK算法

http://blog.csdn.net/x_y_q_/article/details/51999466
//最大流EK算法
//5 4    5是边数 4是节点数
//1 2 40
//1 4 20
//2 4 20
//2 3 30
//3 4 10
//最大流50
#include<stdio.h>
#include<queue>
#include<cstring>
#define arraysize 201
using namespace std;
int maxData = 0x7fffffff;
int capacity[arraysize][arraysize]; //记录残留网络的容量
int flow[arraysize];               //标记从源点到当前节点实际还剩多少流量可用
int pre[arraysize];//标记在这条路径上当前节点的前驱,同时标记该节点是否在队列中
int n,m;                            //n表示边数,m表示结点数
queue<int> myqueue;
int BFS(int src,int des){
    int i;
    while(!myqueue.empty())myqueue.pop();      //队列清空
    for(i=1;i<m+1;++i){pre[i]=-1;}
    pre[src]=0;
    flow[src]= maxData;
    myqueue.push(src);
    while(!myqueue.empty()){
        int index = myqueue.front();myqueue.pop();
        if(index == des) break;            //找到了增广路径
        for(i=1;i<m+1;++i){
            if(i!=src && capacity[index][i]>0 && pre[i]==-1){
               pre[i] = index; //记录前驱
               flow[i] = min(capacity[index][i],flow[index]);//关键:迭代的找到增量
               myqueue.push(i);
            }
        }
    }
    if(pre[des]==-1) return -1;     //残留图中不再存在增广路径
    else  return flow[des];
}
int maxFlow(int src,int des){
    int increasement= 0;int sumflow = 0;
    while((increasement=BFS(src,des))!=-1){
         int k = des;          //利用前驱寻找路径
         while(k!=src){
              int last = pre[k];
              capacity[last][k] -= increasement; //改变正向边的容量
              capacity[k][last] += increasement; //改变反向边的容量
              k = last;
         }
         sumflow += increasement;
    }
    return sumflow;
}
int main(){
    int i;int start,end,ci;
    while(~scanf("%d%d",&n,&m)){
        memset(capacity,0,sizeof(capacity));memset(flow,0,sizeof(flow));
        for(i=0;i<n;++i){
            scanf("%d%d%d",&start,&end,&ci);
            if(start == end) continue;            //考虑起点终点相同的情况
            capacity[start][end] +=ci; //此处注意可能出现多条同一起点终点的情况
        }
        printf("%d\n",maxFlow(1,m));
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值