排涝 网络流--最大流 ek算法

传送门

以前没接触过最大流问题,刚开始以为是用kruscal算法求最小生成树呢,并且题上也是显示最小树的专题:

反正还行吧,捣鼓了两天,总算稍微理解了一下,等会回来整理一下知识点。

 1 #include <iostream>
 2 #include <queue>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <cstdio>
 6 using namespace std;
 7 const int N=201;
 8 int maxData=1<<30;
 9 int capacity[N][N];//记录残留网络的容量:
10 int flow[N];       //标记从源点到当前节点实际还剩多少流量可用
11 int pre[N];        //标记在这条路径上当前节点的前驱,同时标记该节点是否在队列中
12 int n,m;
13 queue<int> q;
14 int bfs(int src,int des)    //找增广路径
15 {
16     int i,j;
17     while(!q.empty())//清空队列
18         q.pop();
19     for(i=1;i<m+1;i++)
20         pre[i]=-1;
21     pre[src]=0;
22     flow[src]=maxData;
23     q.push(src);
24     while(!q.empty())
25     {
26         int index=q.front();
27         q.pop();
28         if(index==des)      //找到增广路径
29             break;
30         for(i=1;i<=m;i++)
31             if(/*i!=src&&*/ capacity[index][i]>0&&pre[i]==-1)
32             {
33                 pre[i]=index;//记录前驱
34                 flow[i]=min(capacity[index][i],flow[index]);//关键:迭代的找到增量
35                 q.push(i);
36             }
37     }
38     if(pre[des]==-1)//残留图中不再存在增广路径
39         return -1;
40     else
41         return flow[des];
42 }
43
44 int maxFlow(int src,int des) //求最大流
45 {
46     int increasement=0;
47     int sumflow=0;
48     while((increasement=bfs(src,des))!=-1)
49     {
50         int k=des;//利用前驱寻找路径
51         while(k!=src)
52         {
53             int last =pre[k];
54             capacity[last][k]-=increasement;//改变正向的容量
55             capacity[k][last]+=increasement;//改变反向的容量
56             k=last;
57         }
58         sumflow+=increasement;
59     }
60     return sumflow;
61 }
62
63 int main()
64 {
65     int i,j;
66     int start,end,ci;
67     while(~scanf("%d%d",&n,&m))
68     {
69         memset(capacity,0,sizeof(capacity));
70         memset(flow,0,sizeof(flow));
71         for(i=0;i<n;i++)
72         {
73             scanf("%d%d%d",&start,&end,&ci);
74             capacity[start][end]+=ci;//注意可能出现多条同一起点终点的情况
75         }
76         printf("%d\n",maxFlow(1,m));
77     }
78     return 0;
79 }
80     
时间: 2024-07-29 19:27:54

排涝 网络流--最大流 ek算法的相关文章

HDU 3549 Flow Problem ( 最大流 -EK 算法)

C++,G++的读取速度差距也太大了 Flow Problem 题意:n,m表示n个点m条有向带权边 问:从1-n最大流多少 裸最大流,拿来练手,挺不错的 #include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <queue> #include <algorithm> const int N = 210; #define

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

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

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

网络流最大流——dinic算法

前言 网络流问题是一个很深奥的问题,对应也有许多很优秀的算法.但是本文只会讲述dinic算法 最近写了好多网络流的题目,想想看还是写一篇来总结一下网络流和dinic算法以免以后自己忘了... 网络流问题简述 一个很普遍的例子就是--你家和自来水厂之间有许多中转站,中转站又由一些水管连接着.我们假设自来水厂的供水是无限的,并且中转站内能存储的水量也是无限的,但是管道有宽又窄,很显然管道内的流量必须小于等于管道的承载范围(否则管道就被撑爆了),那么问题就是要你求出你家最多能收到多大流量的水. emm

最大流 EK算法 (转)

反复寻找源点s到汇点t之间的增广路径,若有,找出增广路径上每一段[容量-流量]的最小值delta,若无,则结束. 在寻找增广路径时,可以用BFS来找,并且更新残留网络的值(涉及到反向边). 而找到delta后,则使最大流值加上delta,更新为当前的最大流值. (粗体表明需要掌握的概念) 关于反向边: 以下摘至HDOJ的课件和网上的: 首先来看一下基本的网络流最大流模型. 有n个点,有m条有向边,有一个点很特殊,只出不进,叫做源点,通常规定为1号点.另一个点也很特殊,只进不出,叫做汇点,通常规定

图论 最大流EK算法

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

HDU 1532 Drainage Ditches(最大流 EK算法)

题目网址:http://acm.hdu.edu.cn/showproblem.php?pid=1532 思路: 网络流最大流的入门题,直接套模板即可~ 注意坑点是:有重边!!读数据的时候要用"+="替换"=". 对网络流不熟悉的,给一篇讲解:http://www.cnblogs.com/ZJUT-jiangnan/p/3632525.html. ?(? ? ??)我是看这篇博客才入门的. 代码: 1 #include <cstdio> 2 #includ

【转】最大流EK算法

转自:http://www.cnblogs.com/kuangbin/archive/2011/07/26/2117636.html 图-1 如图-1所示,在这个运输网络中,源点S和汇点T分别是1,7,各边的容量为C(u,v).图中红色虚线所示就是一个可行流.标准图示法如图-2所示: 其中p(u,v) / c(u,v)分别表示该边的实际流量与最大容量. 关于最大流 熟悉了什么是网络流,最大流也就很好理解了.就是对于任意的u∈V-{s},使得p(s,u)的和达到最大.上面的运输网络中,最大流如图-

最大流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