郁闷。不小心覆盖了重写的。
最原始经典的网络流最大流问题,本身没什么好说的。网上关于网络流和算法的小blog不少,良莠不齐,这里推荐一篇辉夜的blog,里面有各个算法的大致介绍和简单评测。评测数据来自于topcoder上一篇更严谨的英文文章《Maximum Flow: Augmenting Path Algorithms Comparison》,值得一看。另外,维基百科上关于网络流的条目是不错的索引,可以从中找正规学术书籍例如目前最好的网络流专著Network Flows: Theory, Algorithms and Applications,以及一些算法图论方面的书籍。此外,作为算法手册的MIT的算法导论也是不错的,还有一本C++图论算法也可参考。所以这里也就不多说算法内容了。
在此题中实现了两个版本的SAP算法,一个是非递归的ISAP+GAP,相对于上面的blog中的代码去掉了BFS过程并增加可读性。一个是递归的多路增广:一般ISAP算法在得到一个增广轨后在全轨所有节点上均匀的去掉得到的流,而这个算法得到的不是一个增广轨,而是一个增广流:每个节点得到其所有后续节点可增广的流。这里有一个问题是反向狐是否会被多次使用?从算法结果上看是没有问题的,不过正确性需要另外证明。其非递归版是个严格的回溯算法,就没写了。等USACO Training 的全部做完,再回过头来整libary吧。
P.S. 网上一些所谓大牛的代码,实在没法读。叹一个。谁养成这种习惯写代码的话,到公司面试肯定被菜。当然,我贴在这里的代码为了减少行数也用了不少“,”,实际编程中并不推荐。
/* ID: blackco3 TASK: ditch LANG: C++ */ #include <iostream> #include <memory.h> using namespace std; const int _max_node_(200), _max_val_(0x7fffffff); struct t_edge{ int to, cap; t_edge *next, *rev; } *nodes[_max_node_], edge_buf[_max_node_<<1]; int n_node, n_edge, src, sink; int dist[_max_node_], n_dis[_max_node_] ; #ifndef __single_aug_path__ int aug_flow( int cur_node, int in_flow ) { if( cur_node == sink ) return in_flow ; int remain=in_flow ; for( t_edge *p_edge = nodes[cur_node]; p_edge; p_edge = p_edge->next) { if( !p_edge->cap || dist[cur_node] != dist[p_edge->to] + 1) continue ; int cur_flow = aug_flow( p_edge->to , remain>p_edge->cap? p_edge->cap : remain ); p_edge->cap -= cur_flow , p_edge->rev->cap += cur_flow, remain -= cur_flow; if( dist[src]==n_node || !remain ) return in_flow-remain ; } if( !(--n_dis[dist[cur_node]]) ) { dist[src]=n_node; // GAP cut return in_flow-remain; } int min_dist = n_node; for(t_edge *p_edge = nodes[cur_node]; p_edge; p_edge = p_edge->next) min_dist = p_edge->cap ? min(min_dist, dist[p_edge->to]) : min_dist; dist[cur_node] = min_dist + 1, n_dis[ dist[cur_node] ]++; return in_flow-remain ; } int maxflow( ){ int cur_node = src, tot_flow = 0; while( dist[src] < n_node ) tot_flow += aug_flow( cur_node, _max_val_ ) ; return tot_flow; } #else t_edge **cur_edge[_max_node_] ; int prev[_max_node_]; int maxflow( ){ int cur_node = src, tot_flow = 0; memcpy( cur_edge, nodes, sizeof(t_edge*)*n_node ); while( dist[src] < n_node ){ if(cur_node == sink){ // find an augmenting path int aug_flow = _max_val_; for(int i = src; i != sink; i = cur_edge[i]->to ) aug_flow = min(aug_flow, cur_edge[i]->cap); for(int i = src; i != sink; i = cur_edge[i]->to ) cur_edge[i]->cap -= aug_flow, cur_edge[i]->rev->cap += aug_flow; tot_flow += aug_flow, cur_node = src; } t_edge *p_edge; for( p_edge = cur_edge[cur_node]; p_edge; p_edge = p_edge->next) if( p_edge->cap > 0 && dist[cur_node] == dist[p_edge->to] + 1) { cur_edge[cur_node] = p_edge, prev[p_edge->to] = cur_node, cur_node = p_edge->to; break; } if( !p_edge ) { if( !(--n_dis[dist[cur_node]])) break; // GAP cut cur_edge[cur_node] = nodes[cur_node]; int min_dist = n_node; for(t_edge *p_edge = nodes[cur_node]; p_edge; p_edge = p_edge->next) min_dist = p_edge->cap>0 ? min(min_dist, dist[p_edge->to]) : min_dist; dist[cur_node] = min_dist + 1, n_dis[ dist[cur_node] ]++; cur_node = prev[cur_node]; } } return tot_flow; } #endif int main(){ freopen("ditch.in", "r", stdin); freopen("ditch.out", "w", stdout); cin >> n_edge >> n_node ; t_edge *p_buf = edge_buf; for( int i=0; i<n_edge; i++ ){ int from, to, cap ; cin >> from >> to >> cap ; from--, to-- ; p_buf->to=to, p_buf->cap=cap, p_buf->next=nodes[from], nodes[from]=p_buf, p_buf->rev=p_buf+1, p_buf++ ; p_buf->to=from, p_buf->cap=0, p_buf->next=nodes[to], nodes[to]=p_buf, p_buf->rev=p_buf-1, p_buf++ ; } src=0, sink=n_node-1 ; cout << maxflow( ) << endl ; return 0; }
发表评论
-
USACO Training Section 4.2 Cowcycles
2010-01-31 21:11 882英文原题 中文题译 ... -
USACO Training Section 4.2 Job Processing
2010-01-30 17:31 1130英文原题 中文题译 大意: 有N个工件,每个工件要经 ... -
USACO Training Section 4.2 The Perfect Stall 匈牙利算法的递归和非递归实现
2010-01-28 21:21 1641英文原题 中文题译 ... -
USACO Training Section 4.1 Cryptcowgraphy 奶牛密码
2010-01-27 20:58 1195英文原题 中文题译 大意: 奶牛们要从农场逃跑 ... -
USACO Training Section 4.1 Beef McNuggets
2010-01-26 21:37 964英文原题 中文题译 大意: 给定N个正整数, ... -
USACO Training Section 4.1 Fence Loops
2010-01-24 20:14 1062英文原题 大意: 农夫布朗的牧场上的篱笆已经失 ... -
USACO Training Section 3.4 Closed Fences
2010-01-23 17:50 1401英文原题 题意 一个 ... -
USACO Training Section 3.4 American Heritage
2010-01-21 23:19 771英文原题 大意:有一个由最多26个大写字母构成的二叉树 ... -
USACO Training Section 3.4 Raucous Rockers
2010-01-21 23:09 795英文原题 大意:有S首歌,要放到D个CD里。每首歌有一个 ... -
USACO Training Section 3.4 Electric Fence
2010-01-21 12:57 967英文原题 大意:给定一个三角形(0,0),(m,n),( ... -
USACO Training Section 3.3 Riding the Fences
2010-01-20 23:38 1203英文原题 中文题译 经典的求欧拉路径:给定最多两个奇 ... -
USACO Training Section 3.3 Shopping Offers
2010-01-19 22:18 912英文原题 中文题译 这是个与日常生活相关的题。商场促销 ... -
USACO Training Section 3.3 A Game
2010-01-19 20:54 1092英文原题 有如下一个双人游戏:N(2 <= N & ... -
USACO Training Section 3.3 Home on the Range
2010-01-19 19:36 771英文原题 中文题译 大意:给定一个01矩阵,计算其中全为 ... -
USACO Training Section 3.3 Camelot
2010-01-19 03:39 1229英文原题 中文题译 ... -
USACO Training Section 3.2 Sweet Butter
2010-01-19 00:10 1043英文原题 中文题译 大意:农场之间有路构成稀疏无向图,若 ... -
USACO Training Section 3.2 Magic Squares
2010-01-18 23:11 928英文原题 中文题译 大意:有人发明了一种有8个块三种变换 ... -
USACO Training Section 3.2 Feed Ratios
2010-01-18 20:52 1304英文原题 中文题译 大意:给出整数a[i][j]和 ... -
USACO Training Section 3.2 Spinning Wheels
2010-01-18 19:37 866英文原题 中文题译 大意:有五个纺车飞轮,每个都有最多五 ... -
USACO Training Section 3.2 Stringsobits
2010-01-18 01:04 987英文原题 中文题译 大意:求至多有L个1的第i个N位二进 ...
相关推荐
ACM----USACO Training(解题博客网),提供了USACO Training解题的代码,可以参考一下
自己写的usaco_training带代码。供参考,有一道题是cheat的。自己看吧。
usaco测试数据+标程 usaco的section1到section5的所有测试数据 以及标准程序
usaco解题报告,就是usaco.training.gateway上面的题目全解
USACO题解+代码+翻译,好东西,超级齐全,对大家帮助不小,特别是现在nocow挂了
usaco section2.3--section5.5源程序。。。。。。。。。。。。。。。。
[USACO 1.1.4]破碎的项链.cpp
USACO1-5单元AC的代码~ 1 Chapter1 1.1 Section 1.1 1.2 Section 1.2 1.3 Section 1.3 1.4 Section 1.4 1.5 Section 1.5 2 Chapter2 2.1 Section 2.1 2.2 Section 2.2 2.3 Section 2.3 2.4 Section 2.4 3 Chapter3 ...
USACO全部译题 USACO Training Program Gateway
第二行到第 N+1 行: 每行有三个整数,Si, Ei, 和 Ci 第一个星期,农夫约翰随便地让 第一行 两个整数,N (0 ) 和 M
USACO_培训USACO_培训Ride.java-> Gift1.java->
usaco 合集,包括英文原题和中文译题,测试数据以及答案,很全啊!usaco 合集usaco 合集usaco 合集usaco 合集
USACO training 教程翻译合集(清晰明确)
One of the answer of the USACO training exercises.
USACO培训页面美国计算机奥林匹克训练页2015年6月17日开始
usaco的总结和心得 包括了对题目的分了和总结 以及对题目的解法概括
usaco历年测试数据
某些USACO题目的答案,很详细,代码清晰结构良好,算法高效易于调试
usaco 2010-2011 nov news,喜欢usaco的朋友可以看看
USACO题集及答案