[网络流入门,简单题]poj1273Drainage Ditches最大流
2014-07-29 09:44
211 查看
最大流第一题.哦也~~~~~~~~~凭自己的理解写的代码,多做点题,应该会好一点.........
这是EK算法, 根据某网友的描述,该叫"方法",因为实现方式可以多样.最重要的是这个算法的思想. 算法思想源于贪心:
首先从起点开始寻找到终点的可行路,并让其满流.同时建立反向边.比如这题的数据
5条边,4个节点
然后我们随便找了一条路1->2->3->4满流流量为10,建立反向边4->3,3->2,2->1流量为10,并且原正向边容量直接减掉10(在各种帖子里,都用神马f,c函数来搞,我都搞晕了)
然后就这样不断地找增广路,建边.最后就得到答案了.这贪心的关键还在于建反向边,有一篇帖子对其中的理解我表示非常敬佩,至少在我看了若干帖子若干博客若干PPT后
都没明白,却因为这篇博客懂了些.参看:http://blog.sina.com.cn/s/blog_6cf509db0100uy5n.html
看完了基本就能理解这算法的奥妙之处了.总之在各种博客各种教学贴中,大家都是一个语调,我了个擦,这让毫无基础的我情何以堪.前几天有个退役的老队员来讲课,我靠,这
尼玛默认我学过图论呐(=@__@=) ............哎哎哎哎,好吧,从简单的入手,一步一步学....
这是EK算法, 根据某网友的描述,该叫"方法",因为实现方式可以多样.最重要的是这个算法的思想. 算法思想源于贪心:
首先从起点开始寻找到终点的可行路,并让其满流.同时建立反向边.比如这题的数据
5条边,4个节点
1 2 40 1 4 20 2 4 20 2 3 30 3 4 10
然后我们随便找了一条路1->2->3->4满流流量为10,建立反向边4->3,3->2,2->1流量为10,并且原正向边容量直接减掉10(在各种帖子里,都用神马f,c函数来搞,我都搞晕了)
然后就这样不断地找增广路,建边.最后就得到答案了.这贪心的关键还在于建反向边,有一篇帖子对其中的理解我表示非常敬佩,至少在我看了若干帖子若干博客若干PPT后
都没明白,却因为这篇博客懂了些.参看:http://blog.sina.com.cn/s/blog_6cf509db0100uy5n.html
看完了基本就能理解这算法的奥妙之处了.总之在各种博客各种教学贴中,大家都是一个语调,我了个擦,这让毫无基础的我情何以堪.前几天有个退役的老队员来讲课,我靠,这
尼玛默认我学过图论呐(=@__@=) ............哎哎哎哎,好吧,从简单的入手,一步一步学....
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <climits> using namespace std; const int MAX_V = 208; const int MAX_E = 208; const int INF = INT_MAX>>2;//INF完全可以自己设置成100万这样子....写INT_MAX是为了装逼 bool vis[MAX_V]; //用于BFS时的标记 int G[MAX_V][MAX_V]; //邻接矩阵,G[i][j]表示从i到j的残余容量,初始为容量 //这里不用f反向边了,而是直接加到原图中 int prev[MAX_V]; //用于BFS保存增广路,前继节点 /* 比如我们找到的增广路是1->2->3->4,当然在我的实现中编号是0->1->2->3,prev数组就会保存成这个 样子: prev[3] = 2, prev[2] = 1, prev[1] = 0, prev[0] = -1;那BFS返回后如果返回值是true就可以直接利用这个数组还原出路径来了. 又比如增广路是0->6->8->19,那数组中应该是:prev[19]=8, prev[8]=6, prev[6]=0,其它都是-1,因为我们知道要找的是0->19的路径,所以我们令p等于19, 然后看一下prev[19]等于多少,等于8,那就说明倒数第二个点就是8,在令p=prev[p],得到6,那我们就知道倒数第三个点是6,然后p=prev[p],倒数第四个点是0, 嘿,就等于起始点了,哈,就说明路径就是19<--8<--6<--0了,注意是反向的哦.BFS过程还是很朴素的,就和普通的广搜一样. 然后还有就是vis数组,当然需要这个标记数组,不然你找到一个环的话,程序就会卡死了,就一直在那个环里打转了 */ int n, m; bool BFS(int s, int t) { queue<int> Q; memset(vis, false, sizeof(vis)); memset(prev, -1, sizeof(prev)); //no else Q.push(s); vis[s] = true; int now; while (!Q.empty()) { now = Q.front(); Q.pop(); for (int i = 0; i < n; ++i) { if (G[now][i] > 0 && !vis[i]) { prev[i] = now; vis[i] = true; if (i == t) return true; Q.push(i); } }//for } return false; } /* s到t的最大流 */ int EK(int s, int t) { int flow = 0; //最大流 int i, j; while (BFS(s, t)) { int d = INF, p; for (p = t; p != s; p = prev[p]) { d = min(d, G[prev[p]][p]); //d要设置为该路上各段的最小值 } for (p = t; p != s; p = prev[p]) { G[prev[p]][p] -= d; G[p][prev[p]] += d; } flow += d; } return flow; } int main() { while (~scanf(" %d %d", &m, &n)) { memset(G, 0, sizeof(G)); int f, t, c; for (int i = 0; i < m; ++i) { scanf(" %d %d %d", &f, &t, &c); G[f-1][t-1] += c; } printf("%d\n", EK(0, n-1)); } return 0; }本文完
相关文章推荐
- 网络流入门—用于最大流的Dinic算法
- 网络流入门 最大流,带下界,最小费用,EK算法,Dinic算法 模板
- 网络流入门—用于最大流的Dinic算法
- [caioj 1115] 网络流入门1 --- dinic最大流
- hdu3549(网络流入门题-最大流的Ford-Fulkerson算法)
- 最大子段-n个数求和最大且连续的子段-最简单的一维dp,动态规划入门教程,包听懂
- POJ 1459 PowerNetwork 多源点网络流入门(EK算法求最大流)
- 菜鸟学算法--简单的交换和最大公约数算法入门篇
- 网络流入门—用于最大流的Dinic算法
- 网络流入门—用于最大流的Dinic算法
- 网络流(最大流,最小割)基础入门详解
- 网络流入门--最大流算法Dicnic 算法
- 网络流入门—用于最大流的Dinic算法
- HDU 3549 Flow Problem(网络流入门题-最大流的Ford-Fulkerson算法)
- 网络流入门5——(最大流算法—Dinic)
- 网络流入门6—(最大流算法ISAP)
- 数据结构之网络流入门(Network Flow)简单小节
- 入门级算法——最大公约数 最小公倍数 快速幂 简单并查集 排列组合
- 【网络流】最大流最简单的Ford-Fulkerson算法
- 网络流入门—用于最大流的Dinic算法---转载自Comzyh的博客