E_K算法模版

本文介绍了一种求解最大流问题的经典算法——Edmonds-Karp算法,并通过C++代码实现了解决方案。该算法利用广度优先搜索(BFS)来寻找增广路径,通过不断更新残余网络达到求解最大流的目的。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int inf=0x7fffffff;  //定义无穷大
const int max_=250;
int r[max_][max_];   //邻接矩阵大小
bool visted[max_];
int pre[max_];   //前去节点
int n,m;

bool bfs(int s,int t){
   int p;
   memset(visted,false,sizeof(visted));
   memset(pre,-1,sizeof(pre));
   queue<int> q;
   pre[s]=s;
   visted[s]=true;                                    //bfd广度优先寻址,从原点s出发,一旦找到t就返回true,直到不存在从原点s
   q.push(s);                                         //到终点t的简单路。
   while(!q.empty()){                                  //bfs算法用到了栈,会找到>=0条从s到t的简单路
       p=q.front();
       q.pop();
       for(int i=1; i <=n;i++)
       {
           if(r[p][i] >0 && !visted[i])
           {
               pre[i]=p;
               visted[i]=true;
               if(i==t) return true;
                q.push(i);
           }
       }

   }
 return false;
}

int E_K(int s,int t){
    int flow=0,d;                            //E_K算法的核心是增广路径和返向流,只要使用bfd搜出了增广路径,就会将
   while(bfs(s,t)){                          //路径中的每条边进行处理(46,47行),至于为什么反向流也要增加,这个
      d=inf;                                 //我还不是很理解,得看算法导论上的证明。
      for(int i = t;i != s; i = pre[i])
          d=d<r[pre[i]][i]?d:r[pre[i]][i];  //寻找增广路上的最小可增流量
      for(int i=t ; i!= s; i=pre[i])
        {
           r[pre[i]][i]-=d;   //增流,减容
           r[i][pre[i]]+=d;   //减流,增容
        }
        flow+=d;
   }
   return flow;

}





int main()
{
  int u,v,w;
  while(scanf("%d%d",&n,&m)!= EOF){
    memset(r,0,sizeof(r));
    for(int i=0; i< m; i++){
        scanf("%d%d%d",&u,&v,&w);
        r[u][v]+=w;
    }
     printf("%d",E_K(1,n));
  }
  return 0;
}

输入:

第1行:2个正整数N,M。2≤N≤500,1≤M≤20,000。

第2..M+1行:每行3个整数u,v,c(u,v),表示一条边(u,v)及其容量c(u,v)。1≤u,v≤N,0≤c(u,v)≤100。

给定的图中默认源点为1,汇点为N。可能有重复的边。

输出:

第1行:1个整数,表示给定图G的最大流。



样例输入:

6 7
1 2 3
1 3 5
2 4 1
3 4 2
3 5 3
4 6 4
5 6 2
样例输出:

5

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值