xht的二分图与网络流 学习笔记
*【题解】网络流24题 24/24
*网络流24题 题解
[线性规划与网络流24题] 网络流常见模型
一些前置知识
最大匹配数:最大匹配的匹配边的数目
最小点覆盖数:选取最少的点,使任意一条边至少有一个端点被选择
最大独立数:选取最多的点,使任意所选两点均不相连
最小路径覆盖数:对于一个 DAG(有向无环图),选取最少条路径,使得每个顶点属于且仅属于一条路径。路径长可以为 0(即单个点)。
定理1:最大匹配数 = 最小点覆盖数(这是 Konig 定理)
定理2:最大匹配数 = 最大独立数
定理3:最小路径覆盖数 = 顶点数 - 最大匹配数
整理的算法模板合集: ACM模板
问题编号 | 问题名称 | 问题模型 | 转化模型 |
---|---|---|---|
A | 飞行员配对方案问题 | 二分图最大匹配 | 网络最大流 |
B | 太空飞行计划问题 | 最大权闭合图 | 网络最小割 |
C | 最小路径覆盖问题 | 有向无环图最小路径覆盖 | 网络最大流 |
D | 魔术球问题 | 有向无环图最小路径覆盖 | 网络最大流 |
E | 圆桌问题 | 二分图多重匹配 | 网络最大流 |
F | 最长递增子序列问题 | 最多不相交路径 | 网络最大流 |
G | 试题库问题 | 二分图多重匹配 | 网络最大流 |
H | 机器人路径规划问题 | 未解决,假题 | 最小费用最大流 |
I | 方格取数问题 | 二分图点权最大独立集 | 网络最小割 |
J | 餐巾计划问题 | 线性规划网络优化 | 最小费用最大流 |
K | 航空路线问题 | 最长不相交路径 | 最小费用最大流 |
L | 软件补丁问题 | 最小转移代价 | 最短路径 |
M | 星际转移问题 | 网络判定 | 网络最大流 |
N | 孤岛营救问题 | 分层图最短路径 | 最短路径 |
O | 汽车加油行驶问题 | 分层图最短路径 | 最短路径 |
P | 数字梯形问题 | 最大权不相交路径 | 最小费用最大流 |
Q | 运输问题 | 网络费用流量 | 最小费用最大流 |
R | 分配问题 | 二分图最佳匹配 | 最小费用最大流 |
S | 负载平衡问题 | 最小代价供求 | 最小费用最大流 |
T | 深海机器人问题 | 线性规划网络优化 | 最小费用最大流 |
U | 最长k可重区间集问题 | 最大权不相交路径 | 最小费用最大流 |
V | 最长k可重线段集问题 | 最大权不相交路径 | 最小费用最大流 |
W | 火星探险问题 | 线性规划网络优化 | 最小费用最大流 |
X | 骑士共存问题 | 二分图最大独立集 | 网络最小割 |
注:部分题解借鉴 线性规划与网络流24题解题报告
二分图最大匹配问题。
【建模方法】
在二分图的基础上增加源S和汇T。 1、S向X集合中每个顶点连一条容量为1的有向边。 2、Y集合中每个顶点向T连一条容量为1的有向边。 3、XY集合之间的边都设为从A集合中的点到B集合之中的点,容量为1的有向边。
源点:0
外国人:1->m
本国人:m+1->n
汇点:n+1
(源点,外国人,1)
(外国人,本国人,INF)
(本国人,汇点,1)
求网络最大流,流量就是匹配数,所有满流边是一组可行解。
【建模分析】
基本的二分图最大匹配,可以直接用匈牙利算法或Hopcroft_Karp算法解决,更一般的方法是网络最大流。
求出的最大流即为最多的匹配对数。
要得到匹配方案,既是判断各边是否有流量,即判断反向边的权值是否不为0。
有流量的边即为要输出的匹配对。
我是代码
拆点最大流
【问题分析】
有向无环图最小路径覆盖,可以转化成二分图最大匹配问题,从而用最大流解决。
【建模方法】
构造二分图,把原图每个顶点i拆分成二分图X,Y集合中的两个顶点Xi和Yi。对于原图中存在的每条边(i,j),在二分图中连接边(Xi,Yj)。然后把二分图最大匹配模型转化为网络流模型,求网络最大流。
最小路径覆盖的条数,就是原图顶点数,减去二分图最大匹配数。沿着匹配边查找,就是一个路径上的点,输出所有路径即可。
【建模分析】
对于一个路径覆盖,有如下性质:
1、每个顶点属于且只属于一个路径。 2、路径上除终点外,从每个顶点出发只有一条边指向路径上的另一顶点。
所以我们可以把每个顶点理解成两个顶点,一个是出发,一个是目标,建立二分图模型。该二分图的任何一个匹配方案,都对应了一个路径覆盖方案。如果匹配数为0,那么显然路径数=顶点数。每增加一条匹配边,那么路径覆盖数就减少一个,所以路径数=顶点数 - 匹配数。要想使路径数最少,则应最大化匹配数,所以要求二分图的最大匹配。
源点0, 汇点1
图中第i个点: 左部分i, 右部分i + n
(源点,左部分点,1)
(右部分点,汇点,1)
(i的左部分,j的右部分,1),前提是原图中i到j有一条有向边
(点数-最大流)即为最小路径覆盖
注意,此建模方法求最小路径覆盖仅适用于有向无环图,如果有环或是无向图,那么有可能求出的一些环覆盖,而不是路径覆盖。
最后的方案可以利用残量网络用并查集维护。
即从1到n枚举,从每个点向外扫一圈,如果有流从这条边经过,并流向y+n,则合并x与y。
根据网络流的残余流量构造每一条路径(利用并查集维护路径起点),然后从起点递归输出。
我是代码
【问题分析】
枚举答案转化为判定性问题,然后最小路径覆盖,可以转化成二分图最大匹配,从而用最大流解决。
【建模方法】
枚举答案A,在图中建立节点1…A。如果对于i 具体方法可以顺序枚举A的值,当最小路径覆盖数刚好大于N时终止,A-1就是最优解。 【建模分析】 由于是顺序放球,每根柱子上的球满足这样的特征,即下面的球编号小于上面球的编号。抽象成图论,把每个球看作一个顶点,就是编号较小的顶点向编号较大的顶点连接边,条件是两个球可以相邻,即编号之和为完全平方数。每根柱子看做一条路径,N根柱子要覆盖掉所有点,一个解就是一个路径覆盖。 最小路径覆盖数随球的数量递增不递减,满足单调性,所以可以枚举答案(或二分答案),对于特定的答案求出最小路径覆盖数,一个可行解就是最小路径覆盖数等于N的答案,求出最大的可行解就是最优解。本问题更适合枚举答案而不是二分答案,因为如果顺序枚举答案,每次只需要在残量网络上增加新的节点和边,再增广一次即可。如果二分答案,就需要每次重新建图,大大增加了时间复杂度。 优化: 为了避免每次枚举都需要求网络流带来的时间浪费,每次求网络流前把所有弧的当前流置0,即可接着上一次的图直接插入再求。 输出方案: 从1到最大球数枚举,依次找到每个球的左部分连着哪个球的右部分,即可输出每个柱子上的答案。可以直接对着最后ans+1个球的网络图输出答案,注意判断边界即可。 【总结与反思】 这道题代码写起来还是比较简单的,都是模板,但是如何把这道题往网络流的方向去想非常关键。单是看这道花里胡哨的题是不可能想到还能转换为二分图跑最大流。 因此像这种题,就引入了一个“隐式图”的概念。 隐式图顾名思义,大白话来讲就是题目看着不像是图论,但是可以通过一些限制或关联进行建点,连边,最终通过图论的一些算法来求解。 我是代码 然后由超级源点与每个单位连接,边的权值为单位人数 然后跑一下最大匹配 如果最大匹配数等于所有单位的人数和 然后我因为用了成对变换而tot没有赋初值1而WA了一个小时没有找到bug。。。以后tot只写1. 我是代码 【问题分析】 二分图最大独立集,转化为二分图最大匹配,从而用最大流解决。 【建模方法】 首先把棋盘黑白染色,使相邻格子颜色不同。把所有可用的黑色格子看做二分图X集合中顶点,可用的白色格子看做Y集合顶点。建立附加源S汇T,从S向X集合中每个顶点连接一条容量为1的有向边,从Y集合中每个顶点向T连接一条容量为1的有向边。从每个可用的黑色格子向骑士一步能攻击到的可用的白色格子连接一条容量为无穷大的有向边。求出网络最大流,要求的结果就是可用格子的数量减去障碍数再减去最大流量。 【建模分析】 用网络流的方法解决棋盘上的问题,一般都要对棋盘黑白染色,使之成为一个二分图。放尽可能多的不能互相攻击的骑士,就是一个二分图最大独立集问题。有关二分图最大独立集问题,更多讨论见国家队论文《最小割模型在信息学竞赛中的应用》作者胡伯涛。 本题数据范围200, 如果按照奇数建图可以用匈牙利算法侥幸AC,正解还是应该使用最大流算法。 我是代码
源点:100001
汇点:100002
∴数组要开到100005
第i个球:左部分i∗2,右部分i∗2+1
(源点,左部分,1)
(右部分,汇点,1)
(i的左部分,j的右部分,1)要求i<j且i+j为完全平方数
最大流表示把这些球放上去之后,能省下几根柱子。
即,设球数为b,最大流为mf,则(b-mf)根柱子可以容纳b个球。
依次枚举每个球数对应的柱子数,直到得到n个柱子最多放下的球数为止。
那么就此题来看,经思考一会可发现这题的柱子并没有什么实际的作用,所有的操作都是关于珠子的编号的。那么我们可以以每一个珠子为点,若满足条件(编号相加为平方数)就两两连边,那么就可得到一张图,我们再把每一个点进行拆点,就把整张图拆成了一张二分图,最多的珠子实际上就是最长的路径,尽可能少的柱子实际上就是最小路径覆盖。然后跑最大流就行了。
至于最后的输出,在dfs的时候把走的当前的增广路用邻接表(链式前向星)存一下,直接输出即可。
上述隐式图来源E 、圆桌问题(二分图多重匹配)(最大流)【省选/NOI- 】
可以直观的想到,二分图的左边是单位,右边是桌子
由于题目的限制 每个单位只能在一个桌子坐一个人
所以我们就把每个单位向各个桌子连一道流量为1的边,这样每次流一次一个单位只能贡献1个流量,也就是一个人到一个桌子上,满足题意。
由每个圆桌与超级汇点连接,边的权值为圆桌人数
那么就可以 完全安排 否则不能完全安排
然后再枚举一下,如果剩余流量 == 0则该点为方案之一,输出即可。
X、骑士共存问题(最大独立集)(匈牙利 / 最大流)