随笔分类 -  网络流

摘要:这是我在codeforces上做的第一个网络流的题目,思维还不错,讲讲题意:给你n个任务,k个机器,n个任务的起始时间,持续时间,完成任务的获利每个机器可以完成任何一项任务,但是同一时刻只能完成一项任务,一旦某台机器在完成某项任务时,直到任务结束,这台机器都不能去做其他任务最后问你当获利最大时,应该安排那些机器工作,即输出方案刚看到题就想到一个贪心的思路,如果一台机器完成了某项工作,它应该继续去完成接下来最先开始的工作,感觉有点像网络流里面的建图啊,于是继续往这个方向YY,我擦,结果还真可以网络流来搞。具体建图方法:新建源汇S T‘对任务按照起始时间s按升序排序拆点:u 向 u'连一条 阅读全文
posted @ 2012-07-18 15:46 Because Of You 阅读(868) 评论(0) 推荐(0)
摘要:最小点权覆盖集的总权值 + 最大点权独立集的总权值 = 图的总权值所以最大点权独立集的题目都可以转换成最小点权覆盖集的题目注意:图必须是二分图 否则是NP问题两道典型的题目最大点权独立集hdu 1565 http://acm.hdu.edu.cn/showproblem.php?pid=1565将方格黑白染色(类似于国际象棋的棋盘),然后出现二分图了,怎么建边?代码已经很详细了View Code #include<stdio.h>#include<string.h>const int MAX=1010;const int INF=1000000000;struct{ i 阅读全文
posted @ 2012-07-16 19:46 Because Of You 阅读(1050) 评论(0) 推荐(0)
摘要:第一次接触这种类型的建图题,记录一下题意:在一个20*20的方格中,建造一些围墙,使得X和某些A与E和外界都不联通,建造围墙有对应的花费,而对于满足条件的A,有对应的收入。首先2^5枚举哪些A要被围住,然后就要求所需的最小费用,这就是典型的最大流最小割问题。其中X和所枚举的A同源连一条流量为inf的边,E和边界同汇连一条流量为inf的边。以上是watashi的简练题解,我等若菜一开始还没反应过来为什么建好图后的最小割就是把X和一些A与E隔开的最小代价呢?注意,选择了某条边为割边就表示方格中两个格子间的那条围墙被选择了。注意到S集合是X和A,T集合是E和边界,所以求一下最小割后s集合中的点无法到 阅读全文
posted @ 2012-07-12 23:26 Because Of You 阅读(688) 评论(0) 推荐(0)
摘要:这两题有一个共同的特点,都是从矩阵的左上角走到右下角,求最大能获得的权值不过poj 3422可以走k次poj 3422每个点走过一次后,这个点的权值就置零了,相当于经过一次后以后每次经过都没有费用了,所以每个点拆点后u->u' 建两条边一条边容量为1 费用为负的点权另一条边容量为INF,费用为0另外如果一个点能到另一个点,还是老方法u'->v,容量为INF,费用为0;最后要限制总流量为k,即建一个源点向1建一条容量为k,费用为0的边 n*n*2(最后一个点的出点) 向汇点连一条容量为k费用为0的边最后求一下S、T的最小费用流即可View Code #include& 阅读全文
posted @ 2012-04-11 14:24 Because Of You 阅读(492) 评论(0) 推荐(0)
摘要:求给那些边增加容量能增加总的流量显然,不是满流的边,增加也没有用,所以要增加容量的是那些满流的边。做法 求一次最大流 判断有几条边满流且能被源点和汇点搜到View Code #include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int MAX=100005;const int INF=1000000000;struct{ int v,c,next;}edge[1000000];int E,head[MAX];int gap[MAX],cur[MAX];int 阅读全文
posted @ 2012-04-10 20:46 Because Of You 阅读(458) 评论(0) 推荐(0)
摘要:枚举区间建图,好像也可以用多重匹配来做,不过不是很熟新建源点向每头牛连边牛向barns连边barns向汇点连边,边权为barns的容量,其实就是一个二分图最后求最大流就好了View Code #include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int MAX=100005;const int INF=1000000000;struct{ int v,c,next;}edge[1000000];int E,head[MAX];int gap[MAX],cur 阅读全文
posted @ 2012-04-10 20:29 Because Of You 阅读(304) 评论(0) 推荐(0)
摘要:找出若干个环覆盖所有的点,使得总的花费最小因为每个点只能经过一次,所以很快就可想到拆点求最小费用流建图:S->i 费用为0 流量为1i+n->T同上若有边u->vu->v+n 费用为边权,容量为1最后套套模板求一次最小费用流,如果流量等于n,表示每个点都遍历了一次,输出最小费用即可View Code #include <iostream>#include <algorithm>#include <string>#include <stdio.h>#include <string.h>#include <s 阅读全文
posted @ 2012-03-26 11:20 Because Of You 阅读(869) 评论(0) 推荐(0)
摘要:从网上找的模板,测试了一下View Code #include <iostream>#include <algorithm>#include <string>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <memory.h>#include <queue>#include <vector>#include <cmath>using namespace std;int sumFlow;const 阅读全文
posted @ 2012-03-26 11:14 Because Of You 阅读(827) 评论(0) 推荐(0)
摘要:题意:某个冰块上有a只企鹅,总共可以跳出去b只,问是否可能所有的企鹅都跳到某一块冰块上,输出所有的可能的冰块的编号。由于每个点只能跳出去m只企鹅,所以要拆点假如不拆点,一个点到另一个点可能会跳多于m只企鹅通过拆点后u->u'间的容量来完成题目的要求(对点的一些限制)建图:i->i+n 容量为m i+n->j容量为INF新建源点s,s->i的容量为i点企鹅的个数然后枚举汇点求最大流就可以判断某个点是否符合条件View Code #include<stdio.h>#include<cmath>#include<string.h># 阅读全文
posted @ 2012-03-24 01:22 Because Of You 阅读(739) 评论(0) 推荐(0)
摘要:最大权闭合图的证明:http://www.cnblogs.com/wuyiqi/archive/2012/03/12/2391960.html结论:正的权值的和-建图后的最小割的容量选择了一条边就会选择两个点,边的花费为正,点的花费为负,把边看成点,这个点向两个端点连一条边,表示选择这条边就会选择这两个点然后题目就相当于最大权闭合图的模型了题意:有n个点,m个选择,建造n个点各自需要一定花费,每个选择有一定的获利,会选择两个点,当然也要花费求最大的获利每个选择看成是获利点,每个点看成是花费点,新建源点向获利点建边,权值为获利的大小,花费点向汇点建边,权值为花费的大小每个选择向相应的两个点连一条 阅读全文
posted @ 2012-03-23 14:35 Because Of You 阅读(704) 评论(0) 推荐(0)
摘要:先判断有无可行流,再求最大流http://blog.csdn.net/fp_hzq/article/details/6772320在上一题上下界流中,我们已经知道了怎么判断无源汇上下界网络流有无可行流把每一天看成一个点,每个女孩也看成一个点,增加源和汇s、t,源向每一天连上[0,d]的边,每一天与每个女孩如果有拍照任务的话连上[l,r]的边,每个女孩与汇连上[g,oo]的边,于是构成一个有上下界的图所以这道题目我们可以转换一下只要连一条T → S的边,流量为无穷,没有下界,那么原图就得到一个无源汇的循环流图。接下来的事情一样:原图中的边的流量设成自由流量ci – bi。新建源点SS汇点TT,求 阅读全文
posted @ 2012-03-15 19:41 Because Of You 阅读(1250) 评论(0) 推荐(0)
摘要:这道题目算是让我学到了不少建图的细节题目保证从s到t有T条无相同道路的路径,即每条边只能用一次,每个点可以多次经过然后要求所有的路径中最大的边的最小值每条边只能用一次,可以联想到网络流,边容量为1求最小的最大可以用二分判断二分的值是否满足条件:s、t的最大流是否>=T讲一下建图的细节双向建图,即满足条件的每条边的容量都为1,可以双向流而对于zoj 3583,每个点只能经过一次(每条边当然也只能经过一次),而且是无向图,所以也需要双向流,但是由于一个点只能经过一次,就需要拆点了,拆点后再求最大流就能保证最大的流只经过每个点最多一次。View Code #include<stdio.h 阅读全文
posted @ 2012-03-14 23:08 Because Of You 阅读(721) 评论(0) 推荐(0)
摘要:对于每个点有两个数in[i],out[i],表示拆掉i的所有入边的代价和拆掉所有出边的代价对于一条边(u,v)有两种操作可以将其拆掉,要么拆除u的所有出边,要么拆除v的所有入边,两个操作至少要有一个被执行这就相当于最小点权覆盖(可以参考那篇最小割的论文)中的一条边中的任意一个点都可以覆盖这条边所以,一个操作看做一个点,一条边相当于连接两个操作的边,一个最小点权覆盖的模型就建立好了建图过程如下:新建源点汇点s、t对于每个点u,拆成u u+ns->u 容量为out【u】;u+n->t容量为in[u]对于每条边u->vu->v+n,容量为无穷大求最小割,可得最小代价,(画个简 阅读全文
posted @ 2012-03-13 11:23 Because Of You 阅读(1140) 评论(0) 推荐(0)
摘要:由上一篇可得最大权闭合图的权值为sum-max_flowsum为正的权值和,max_flow为重新建图后的最大流求最大流后,在残留网络中从s出发dfs能搜到点都为最大权闭合图中的点,即这个最小割对应的是最大权闭合图View Code #include<stdio.h>#include<string.h>const int MAX=100005;const int INF=1000000000;struct{ int v,c,next;}edge[1000000];int E,head[MAX];int gap[MAX],cur[MAX];int pre[MAX],dis 阅读全文
posted @ 2012-03-12 23:35 Because Of You 阅读(861) 评论(0) 推荐(0)
摘要:[网络流]最大权闭合图(转载)来自:http://hi.baidu.com/%C6%AE%BB%A8%C4%EA%B4%FA/blog/item/45d4bb1765e7044721a4e960.html以下内容参考 胡伯涛 《最小割模型在信息学竞赛中的应用》,感谢他为我们提供这么优秀的论文。看不懂以上论文的同学,可以试试看一下以下内容,本文无大量的数学符号,方便阅读理解。首先我们由一道题来引入,见[线性规划与网络流24题 2] 太空飞行计划问题。这道题中,实验依赖于仪器,而实验和仪器都有权值,且仪器为负,实验为正。这里闭合图的概念就很好引出了。在一个图中,我们选取一些点构成集合,记为V,且集 阅读全文
posted @ 2012-03-12 16:10 Because Of You 阅读(14342) 评论(3) 推荐(20)
摘要:网上摘的一些知识点基础知识 欧拉回路是图G中的一个回路,经过每条边有且仅一次,称该回路为欧拉回路。具有欧拉回路的图称为欧拉图,简称E图。 无向图中存在欧拉回路的条件:每个点的度数均为偶数。 有向图中存在欧拉回路的条件:每个点的入度=出度。 欧拉路径比欧拉回路要求少一点: 无向图中存在欧拉路径的条件:每个点的度数均为偶数或者有且仅有2个度数为奇数的点。 有向图中存在欧拉路径的条件:除了2个点外,其余的点入度=出度,且在这2个点中,一个点的入度比出度大1,另一个出度比入度大1。 欧拉路径的输出:经典的套圈算法。 下面来重点讲讲混合图的欧拉回路问题。 混合图就是边集中有有向边和无向边同时存在。这时候 阅读全文
posted @ 2012-03-12 11:26 Because Of You 阅读(584) 评论(0) 推荐(0)
摘要:两种做法1:本来想的是枚举每个点u,从s搜到u,再从t搜到u,如果两条路径只有u这一个公共点,则u可以在简单路径上,后来举出了一个反例就推翻掉了,囧。。。。。。但现在发现这个想法是下一个想法的铺垫。模型是:是否存在s->u的一条路径与t->u的另一条路径只有u这一个交点单纯的搜索很难弄,比如广搜,搜到的路径都是最短路径,很容易就可以举出反例推翻掉。举个例子:先发一张比较挫的图片这个例子中,每个点都可以成为s->t的简单路径上的点,所以答案是0.如果用搜索,很可能s->y->v->u t->v->u,而忽略了s->y->x->u导 阅读全文
posted @ 2012-03-11 23:39 Because Of You 阅读(593) 评论(0) 推荐(0)
摘要:类型:无源汇可行流参考自()http://hi.baidu.com/evelynhe/blog/item/f1c5ba2fcbe674271e3089ad.html每条边的容量满足一定的限制,即有一个上限值,也有一个下限值上界用ci表示,下界用bi表示。下界是必须流满的,那么对于每一条边,去掉下界后,其自由流为ci– bi。主要思想:每一个点流进来的流=流出去的流对于每一个点i,令Mi= sum(i点所有流进来的下界流)– sum(i点所有流出去的下界流)如果Mi大于0,代表此点必须还要流出去Mi的自由流,那么我们从源点连一条Mi的边到该点。如果Mi小于0,代表此点必须还要流进来Mi的自由流, 阅读全文
posted @ 2012-02-29 16:24 Because Of You 阅读(1030) 评论(0) 推荐(0)
摘要:求的最大流后依次从源点和汇点开始dfs 如果能搜到的点数之和等于总的点数,最小割唯一,否则不唯一View Code #include<stdio.h>#include<string.h>const int MAX=100005;const int INF=1000000000;struct{ int v,c,next;}edge[1000000];int E,head[MAX];int gap[MAX],cur[MAX];int pre[MAX],dis[MAX];void add_edge(int s,int t,int c,int cc){/*加边的时候同时加两条, 阅读全文
posted @ 2012-02-27 16:28 Because Of You 阅读(384) 评论(0) 推荐(0)
摘要:由行向列建图,增加两个源汇点,源点向行连边,容量为该行的花费,列向汇点连边,容量为该列的代价,一个伞兵的位置为x,y,则从x行向y列连一天容量为无穷大的边,最后求最大流(最小割的容量)即可View Code #include<cstdio>#include<cstring>#include<cmath>const int MAX=100005;const double INF=1000000000;struct{ int v,next; double c;}edge[1000000];int E,head[MAX];int gap[MAX],cur[MAX] 阅读全文
posted @ 2012-02-27 15:50 Because Of You 阅读(241) 评论(0) 推荐(0)