随笔分类 -  最大流&二分匹配

摘要:题意:给定N个点,M条边,M >= N-1。已知M条边都有一个权值,已知前N-1边能构成一颗N个节点生成树,现问通过修改这些边的权值使得最小生成树为前N条边的最小改动总和为多少?分析:由于计算的最小改动且为最小生成树则显然前N-1条边肯定权值都减少,后面的边权值都增加。由于选择的边为前N-1得到最小生成树,因此首先将N-1条边构图,然后对后面的每一条边,那么这条边所构成的环中,有任意一条边的a与该边b,设原始权重为w[a],w[b],改变量为d[a],w[b],则有w[a] - d[a] = 0表现在图中就是每个点对之间连了一条权值为0的边,这样才能够保证求出来的值都是正值。简要分析其原 阅读全文
posted @ 2013-09-07 21:17 沐阳 阅读(1116) 评论(0) 推荐(0) 编辑
摘要:题意:给定一个分层图,即只能够在相邻层次之间流动,给定了各个顶点的层次。要求输出一个阻塞流。分析:该题直接Dinic求最大流TLE了,网上说采用Isap也TLE,而最大流中的最高标号预流推进(HLPP)能够直接秒掉这一题。当然还有一种挽救的方式就是首先进行一次贪心预流,然后进行dinic。也是第一次听说还有贪心预流这回事,所以找了一份代码特地学习了一番。具体步骤如下:1.首先将所有节点按照层次进行排序,对每个节点有in[i]和out[i]两个属性,前者表示能够流入到该节点的流量,后者表示能够流出该节点的流量;2.从层次最低的节点(即源点)开始,设in[S] = inf,表示源点能够进入无限的流 阅读全文
posted @ 2013-07-21 18:54 沐阳 阅读(633) 评论(1) 推荐(1) 编辑
摘要:题意:给定一个最小费用流的模型,根据给定的数据判定是否为最优解,如果不为最优解则给出一个比给定更优的解即可。不需要得出最优解。解法:由给定的数据能够得出一个残图,且这个图满足了最大流的性质,判定一个残图是否满足最小费用最大流的判定依据类比于最大流中的层次图的构建,此时只需要判定图中是否存在负环即可。在写的过程中由于图中的编号和抽象了之后的编号有一个变换关系,所以处理要小心,一开始直接写了个最小费用最大流,通过费用来判定是否为最优TLE。找负环的时候,该题宜从汇点开始遍历,因为源点发出的边肯定全部满流(由于要疏散所有的人),而市政大楼与避难所在内部又分别没有边相连,所以要形成回路就必定会经过汇点 阅读全文
posted @ 2013-07-15 10:36 沐阳 阅读(1240) 评论(0) 推荐(0) 编辑
摘要:题意:给定若干个房间,现在这些房间之间能够相互的联通,房间门是单向的,现在问一些门中都有人的情况下,至少要堵住多少条门才能够使得无法到达终点。解法:显然这是一个集合的分割问题,即求这样的一个割:使得终点房间与某些存在人的房间的一个分割,题中求的最少的人就是求解一个最小割。将问题转化为网络流求解。通过建立从超级源点到存在人的一些房间,那么从汇点反向遍历寻找这样的一个割。如果从源点到有人房间的边满流,那么反向遍历一定不会将这个节点划分到汇点集合里面去,如果该边不满流的话,如果划分到了汇点集合,则表明存在从源点到汇点的流量,于最大流相悖。因此所求既满足题意。代码如下:#include <cst 阅读全文
posted @ 2013-05-06 16:16 沐阳 阅读(364) 评论(0) 推荐(0) 编辑
摘要:题意:给定一个无向图,要求判定分离两个点的最小割是否唯一。解法:在求出最大流的基础上,从源点进行一次搜索,搜索按照未饱和的边进行,得到顶点子集S的顶点个数;再从汇点反向搜索未饱和的边,得到子集T的顶点个数,判定顶点数相加是否等于总共的顶点数。http://blog.csdn.net/waitfor_/article/details/7330437的文章写的很好,这里截取文中所画的两个图进行说明。(1)正向搜索集合为S,反向搜索集合为T,cnt1和cnt2都是最小割边。很显然M还存在着最小割边,因为从M到T的残余网络也没有流向T的容量了。(2)增加E1这部分边的容量将直接导致网络最大流量增加。增 阅读全文
posted @ 2013-05-01 21:33 沐阳 阅读(1449) 评论(0) 推荐(0) 编辑
摘要:题意:地球和火星发生了战争。现火星人要在一个N*M的网格降落他们的伞兵,而我们要消灭掉这些伞兵。有这样一种武器,它能够瞬间摧毁网格上某一行或者是某一列的所有目标。然而在哪一行或者哪一列部署这样的武器的花费是不同的。因此要求给出一种最省的方式使得所有的伞兵都能够被消灭。花费的定义是某种部署方案能够消灭所有伞兵,然后根据给定的行列费用把它们相乘即为。希望这一天永远不要到来吧。解法:首先这题应该让无数少男少女想到了二分匹配中做到的关于行列匹配的题吧。只不过这题中并不是所有的行和列等价。而是行列的权值各不相同。类比于原来问题中的最小顶点覆盖,这里就是一个最小点权覆盖,也即使用最小点权和的点集使得所有的 阅读全文
posted @ 2013-05-01 17:37 沐阳 阅读(697) 评论(0) 推荐(0) 编辑
摘要:题意:给定一个混合图,所谓混合图就是图中既有单向边也有双向边,现在求这样的图是否存在欧拉回路。解法:首先回顾下有向图的欧拉回路的条件是什么:所有的节点出度等于入度。现考虑到下面的这个图的转化过程:假设上方图中的A,B两点代表在有向图存在欧拉回路时任意两点之间连边关系,显然有两个点的入度等于出度。现在考虑改变某条边的关系,那么可以看到新的入度和出入如下图,这一有一个不变量就是任意一个点的入度和出度之差的奇偶性不变。现列步骤如下:1.为任意一条无向边选择一个方向。如果存在欧拉回路的话,那么可以得到每个点入度于出度差至少应满足为偶数。否则一定不能够构成欧拉回路。2.在满足上述条件的基础上,我们需要对 阅读全文
posted @ 2013-05-01 10:57 沐阳 阅读(2070) 评论(0) 推荐(0) 编辑
摘要:题意:有F快草地,每块草地上有若干奶牛也有避雨点,每个避雨点只能够容纳一定量的奶牛。草地之间有边。现在问所有牛全部到达避雨点的时间是多少?解法:这题和POJ-2112非常相似,做法也差不多,folyd处理之后二分枚举答案。该题的构图稍微难一点,需要考虑到一个流量的控制问题,即当某一点多余的流量流出去后必须在下一个点停止住。自己是把一个点拆成了3个点进行控制,后面学习了别人拆成两个点也能完成。代码如下:#include <cstdlib>#include <cstdio>#include <cstring>#include <iostream>#i 阅读全文
posted @ 2013-04-30 23:31 沐阳 阅读(270) 评论(0) 推荐(0) 编辑
摘要:题意:给定一些散列的源点会汇点,求解网络流。代码如下:#include <cstdlib>#include <cstring>#include <cstdio>#include <iostream>#include <algorithm>using namespace std;const int INF = 0x3fffffff;const int SS = 105, TT = 106;int n, np, nc, m;struct Edge { int v, c, next; };Edge e[100000];int idx, he 阅读全文
posted @ 2013-04-30 20:32 沐阳 阅读(245) 评论(0) 推荐(0) 编辑
摘要:题意:有C头奶牛,K个挤奶站,每个挤奶器最多服务M头奶牛,奶牛和奶牛、奶牛和挤奶站、挤奶站和挤奶站之间都存在一定的距离。现在问满足所有的奶牛都能够被挤奶器服务到的情况下,行走距离的最远的奶牛的至少要走多远。解法:又是一个求最大中的最小问题,很容易想到用二分枚举来得出正确的答案。首先对整个图做一个floyd,求出两两之间的最短路,然后再枚举一个最大距离值进行构边,每次询问是否能够全部奶牛都能够被匹配到。注意:距离为0是当作INF处理,否则在floyd取min的时候要特判。代码如下:#include <cstdlib>#include <cstdio>#include &l 阅读全文
posted @ 2013-04-30 17:05 沐阳 阅读(871) 评论(0) 推荐(0) 编辑
摘要:题意:很裸,M和N的顺序别搞错了。代码如下:#include <cstdlib>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;int N, M;const int INF = 0x3f3f3f3f;struct Edge { int v, c, next; }e[500];int idx, head[205];int level[205];int front, tail, que[205];vo 阅读全文
posted @ 2013-04-30 14:56 沐阳 阅读(204) 评论(0) 推荐(0) 编辑
摘要:题意:一个农夫要把养殖的猪卖出去,现有M个猪圈,农夫自己没有猪圈的钥匙。现有N个客户要来买猪,每个客户手中有Ai把钥匙,分别表示成猪圈的编号,并且每个客户需要买一定的猪。这些客户依次过来(编号从小到大),现在农夫可以选择如何将这些猪卖给每一个客户,只要头数不超过需求即可。农夫在处理好每一笔交易后能够将打开的猪圈门之内的猪任意分配。现在问农夫能够卖出最多的猪的数量。解法:通过这一题,发现构边的时候其实是有很多技巧的,这题如果把猪圈放到图中的话那么将成为一道不可做题。原因是时间复杂度和空间复杂度太高了。其实可以画出一个简图,然后再通过合并边和合并点来简化构图。由于农夫能够在打开猪圈后任意分配猪。因 阅读全文
posted @ 2013-04-30 14:40 沐阳 阅读(326) 评论(0) 推荐(0) 编辑
摘要:题意:给定两个关系矩阵,分别表示雇主和雇员的相互好感度,好感度为1最优,N最差。如果一个人与好感度为P的人匹配的话,差值为P-1,现在要求是的总共的差值最小的匹配方法,并且输出所有的匹配方案。解法:将两两关系矩阵转化为边上的权值,然后进行一次最大匹配,最后dfs枚举输出结果,数据中给的矩阵上下颠倒了。代码如下:#include <cstdlib>#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>#include <cmath> 阅读全文
posted @ 2013-04-10 23:04 沐阳 阅读(348) 评论(0) 推荐(0) 编辑
摘要:做这题的时候突然觉得每次修改一次可行标就一定能够找到增广路,因此把while(1)改成了int T = 2; while(T--) {}谁知道WA了,这就比较纠结了,后面手动模拟了一组数据才知道不在交错树的点不一定不在已经存在的匹配中,增加的可行边右端点可能就落在了一条匹配边上,那么这样一来并不能保证找到一条增广路。这样也就解释了为什么对于slack[]数组每次进行一个更新,因为这个值由于循环次数的增加可能多次被利用到,没有找到增广路,那么原来的那条交错树一定还会边遍历一遍,而且会有新的节点加入到S和T集合(其实反正都会遍历一遍,那么不更新slack数组,dfs过程中也会自动缩小)。题意:有N 阅读全文
posted @ 2013-04-10 07:53 沐阳 阅读(367) 评论(0) 推荐(0) 编辑
摘要:题意:给定一个网格图,图上有一些人要到一些房子当中去,人和房子的数量一样多,人和房子的曼哈顿距离作为行走的开销,问所有人走到房子中的最小开销。解法:将人和房子之间两两之间建立带权边,权值为曼哈顿距离的相反数,这样问题就转化为最大权值匹配问题。代码如下:#include <iostream>#include <cstdlib>#include <cstring>#include <cstdio>#include <algorithm>using namespace std;const int INF = 0x3f3f3f3f;int N 阅读全文
posted @ 2013-04-09 19:40 沐阳 阅读(285) 评论(0) 推荐(0) 编辑
摘要:题意:给定一群人的姓名和昵称,给定了一些关系,现在要求判定姓名和昵称能够一一对应的有哪些?解法:一开始直接使用藏匿点的所有人和邮件进行构边,再用删除来判定,结果出错,为什么呢?因为我们将藏匿点的所有人和邮件连边确定的就是一种可能关系,然而题目中还隐藏了许多的可能关系,比如某人在藏匿点但是没有发邮件,那么其和其他未出现的昵称之间存在可能关系。正确的解法是确定不可能关系,因为这样更加简单,在藏匿点外的人不可能与邮件有关系。初始化所有人和所有昵称都有关系,通过排除不可能的关系即确定了可能的关系。之后再枚举每一条边,将其删除看通过最大匹配是否减小来断定这条边是不是被唯一对应。注意:如果某一组名字-昵称 阅读全文
posted @ 2013-04-08 21:09 沐阳 阅读(512) 评论(0) 推荐(0) 编辑
摘要:题意:给定一个网格,现在某些格子坐标中有一个小行星,现有一种武器能够击穿一行或者是一列的小行星,问最少使用多少次这种武器能够销毁所有的小行星。解法:由于每一个点只要被行或者列覆盖到就可以,因此可以将某一点所在的行和列进行匹配,问题就转化为求一个最小顶点覆盖就可以了,因为这样能够保证每一条边都有一个顶点在点集内。也即每个小行星都能够被所在的行或者是所在的列覆盖到。代码如下:#include <iostream>#include <cstring>#include <cstdio>#include <cstdlib>#include <algo 阅读全文
posted @ 2013-04-08 18:28 沐阳 阅读(255) 评论(0) 推荐(0) 编辑
摘要:题意:有N个十字路口,这些十字路口通过M条路连接,边是单向的,现在要派一些伞兵去空袭这些十字路口,每个伞兵可以沿着一条路空袭沿路的十字路口,问最少要派出多少伞兵。解法:对于有向无环图求最小的路径覆盖数相当于将原图中的点拆开后,求一个最大匹配数,然后用顶点数减去最大匹配数就是最小路径覆盖了。代码如下:#include <iostream>#include <cstdlib>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int N, M 阅读全文
posted @ 2013-04-08 13:46 沐阳 阅读(205) 评论(0) 推荐(0) 编辑
摘要:题意:有许多男女同学,他们之间互相喜欢,现要求出一个最大的独立子集出来。解法:由于题目中说明了这种喜欢关系只存在于男女之间,因此可以大胆的拆点构图,因为男的喜欢的必定是女的,而女的之间不可能存在边(喜欢关系)。最大独立子集=顶点数-最大匹配数。由于是拆点构图,需要对最后的结果除以2。代码如下:#include <cstdlib>#include <cstring>#include <cstdio>#include <iostream>#include <algorithm>using namespace std;int N, matc 阅读全文
posted @ 2013-04-07 10:46 沐阳 阅读(278) 评论(0) 推荐(0) 编辑
摘要:题意:有一块土地,某些地方被挖去了,现在允许以每相邻的两块进行出售,问最多能出售多少块出去。解法:其实相邻即曼哈顿距离为1,那么最经典的方式当然是黑白染色棋盘来进行构图了,但是这题数据量太大了,虽然知道会MLE或者TLE,不过还是写了一遍。正确的解法当然是把所有的合法的点抠出来,题目已经告诉我们这样的点不会超过50个,所以不用当心任何问题,然后就是枚举两两组合是否相邻进行构图,然后求出最大匹配出售。这个枚举过程其实也是将图进行了拆点处理,曼哈顿距离为1的组合方式确保了从一点连出去的边的另一端点内部曼哈顿距离一定不为1,所以拆点后仍可以将坐标和为奇数的点看做X部,坐标和为偶数的点看做Y部,所不同 阅读全文
posted @ 2013-04-07 10:24 沐阳 阅读(313) 评论(0) 推荐(0) 编辑

点击右上角即可分享
微信分享提示