EK算法模板

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
int dp[100][100],pre[100];
const int tmin=999999999;
int maxflow;
void EK(int start,int end,int n){
    while(1){
        queue<int>q;
        q.push(1);//源点为1,进队
       int  minflow=tmin;
        memset(pre,0,sizeof(pre));//初始化增广路径数组,题目中的顶点是从1开始的
        while(!q.empty()){//bfs找增广路
            int u=q.front();
            q.pop();
            for(int i=1;i<=n;i++){
                if(dp[u][i]>0&&!pre[i]){//pre[i]除了记录当前顶点的父亲,还记录当前顶点有没被访问过
                    pre[i]=u;
                    q.push(i);
                }
            }
        }
        if(pre[end]==0)//顶点的父亲为空,表示找不到增广路,很容易理解吧。。
            break;
        for(int i=end;i!=start;i=pre[i]){//找出增广路中最小残余量
            minflow=min(dp[pre[i]][i],minflow);
        }
        for(int i=end;i!=start;i=pre[i]){//更新增广路中正反向弧的流量
            dp[pre[i]][i]-=minflow;
            dp[i][pre[i]]+=minflow;
        }
        maxflow+=minflow;
    }
}
int main(){
   int count=0;
   int n,m;
   int t;
   scanf("%d",&t);
   while(t--){
        scanf("%d%d",&n,&m);
       memset(dp,0,sizeof(dp));
       memset(pre,0,sizeof(pre));
       count++;
       int u,v,w;
       for(int i=1;i<=m;i++){
           scanf("%d%d%d",&u,&v,&w);
           dp[u][v]+=w;
       }
       maxflow=0;
       EK(1,n,n);
       printf("Case %d: %d\n",count,maxflow);
   }
   return 0;
}
时间: 2024-11-11 20:13:26

EK算法模板的相关文章

POJ 1273 Drainage Ditches(我的EK算法模板)

题意:给你n条边,目标位置t:接下来是每条边,包括起点,终点,容量: 感想:第一道最大流的代码,这道题是我更深地理解了Ek算法,不过这道题有个超坑的情况,那就是出现重边的情况==! 思路:EK算法 AC代码: #include<stdio.h> #include<string.h> #include<algorithm> #include<queue> using namespace std; #define INF 100000000 #define N

最大流的EK算法模板

模板题:洛谷p3376 题目大意: 给出一个网络图,以及其源点和汇点,求出其网络最大流. 基本思路: 套模板 EK的时间复杂度O(V*E^2) EK算法思路: 1.通过BFS拓展合法节点(每个节点在本次BFS中仅遍历一次),找到汇点,并记录每个节点的前面节点(pre)(若找不到增广路,算法结束) 2.通过BFS的记录,从汇点回溯回源点,记录下每条弧流量的**最小值**minn, ans += minn(否则就会超出某条边的限制流量) 3.将所有经过的边的流量减去minn,反向边加上minn 4.

最大流EK算法模板

最近学了下最大流算法,大概思想算是懵懵懂懂了,现在想把模板记录下来,以备后面深刻学习之用. 1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 5 #define _clr(x, y) memset(x, y, sizeof (x)) 6 #define Min(x, y) (x < y ? x : y) 7 #define INF 0x3f3f3f3f 8 #define N 210 9 10 in

HDU-1532 Drainage Ditches (最大流,EK算法模板)

题目大意:最大流的模板题...源点是0,汇点是n-1. 代码如下: # include<iostream> # include<cstdio> # include<cmath> # include<string> # include<vector> # include<list> # include<set> # include<map> # include<queue> # include<

图论 最大流EK算法

今天接触了最大流,网上有很多ppt,耐心看下,再敲几遍代码大概就能懂意思了 EK 算法 关键是要理解要理解反悔的这个意思,因为每次当你选择了一种方式,但是这种方式不一定是最优的所以我们要再来建立一条反向边, 来完成反悔的策略 然后就是大概一直找增广路,改变最大的值,一直到找不到增广路为止 现在把模板的代码附上,并且给予注释 下面有两种方式一种是紫书上刘汝佳的代码,还有种是用链式前向星,还有种是dfs的方式,之后会继续补充 分别给出两种代码 struct Edge{ int from,to,cap

Codeforces Round #304 (Div. 2) E. Soldier and Traveling 最大流 Dinic EK 算法

E. Soldier and Traveling time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output In the country there are n cities and m bidirectional roads between them. Each city has an army. Army of the i-th ci

【转】网络最大流——EK算法详解

原文  http://blog.csdn.net/a1dark/article/details/11177907 EdmondsKarp算法,简称EK算法,O(m^2n) 因为是初学教程,所以我会尽量避免繁杂的数学公式和证明.也尽量给出了较为完整的代码.本文的目标群体是网络流的初学者,尤其是看了各种NB的教程也没看懂怎么求最大流的小盆友们.本文的目的是,解释基本的网络流模型,最基础的最大流求法,即bfs找增广路法,也就是EK法,全名是Edmond-Karp,其实我倒是觉得记一下算法的全名和来历可

POJ1273 最大流 EK算法

套了个EK的模板 //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #include <stdio.h> #include <iostream> #include <climits> #include <cstring> #include <cmath> #include <stack> #include <queue> #i

tarjan算法模板

var {left表示点 root 没离开栈 vis表示点 root 有没有被访问过} i,n,m,now,time,color,top:longint; v:array[0..10001] of record start:longint;end; e:array[0..100001] of record y,next:longint;end; dfn,low,stack,encolor:array[0..10001] of longint; vis,left:array[0..10001] o