解题报告 (九) 二分图最大匹配



二分图最大匹配 解题报告

一、最大匹配模板题

  • 地址:二分图最大匹配模板
  • 提供几个裸的二分图最大匹配的题,直接套模板,可以用来检验模板的正确性和完备性。

HDU 1083 Courses

HDU 2063 过山车

HDU 1528 Card Game Cheater

HDU 1179 Ollivanders: Makers of Fine Wands since 382 BC.

PKU 2584 T-Shirt Gumbo

HDU 2444 The Accomodation of Students

二、染色 + 最大匹配

HDU 2194 Help the vendor and get some M

  • 链接:HDU 2194 Help the vendor and get some M _
  • 题意:给定 n ( n < = 50 ) n(n <= 50) n(n<=50) 个数字和 1 个 k ( k < = 25 ) k(k <= 25) k(k<=25),挑出最多的数对 ( i , j ) (i,j) (i,j) 满足 a [ i ] = = a [ j ] ∗ k a[i] == a[j]*k a[i]==a[j]k
  • 题解:首先当 k = 1 k=1 k=1 的时候,很显然答案为 n / 2 n/2 n/2;当 k > 1 k > 1 k>1 时,如果 a [ i ] = = a [ j ] ∗ k a[i] == a[j]*k a[i]==a[j]k ,则建立一条 i i i j j j 的有向边: i → j i \to j ij,然后对整个图进行 01 间隔染色,染色为0的作为二分图左边的点,染色为1的点作为二分图右边的点,求一次二分图最大匹配。

HDU 4185 Oil Skimming

  • 链接:HDU 4185 Oil Skimming
  • 题意:给定一个 n ∗ n ( n < = 600 ) n*n(n <= 600) nn(n<=600) 格子,只有 ‘#’ 和 ‘.’,要求选择尽量多的 1 X 2 或者 2 X 1 的 ‘#’ ,求这个最大数量。
  • 题解:对于每个 ‘#’ 进行编号,如果有两个 ‘#’ 相连,则建立从 x → y x \to y xy y → x y \to x yx 的双向边,然后遍历一遍图,对二分图进行01 间隔染色,染色为0的作为二分图左边的点,染色为1的点作为二分图右边的点,求一次二分图最大匹配。
  • 当然还有一个更加粗暴的办法,因为染色后 0 在左边,1在右边,那么可以认为 1 在左边 ,0 在右边,最后求出的最大匹配是一样的,也就是说 0 和 1 的点集加起来就是全集,所以可以不进行染色,直接对所有点求最大匹配,最后除 2 即可。

HDU 1507 Uncle Tom’s Inherited Land

HDU 3729 I’m Telling the Truth

  • 链接:HDU 3729 I’m Telling the Truth
  • 题意: n ( n < = 60 ) n(n <= 60) n(n<=60) 个学生,每个人都说了自己所在的排名名次区间 [ X i , Y i ] [X_i,Y_i] [XiYi],其中可能存在有人说谎,问最多有多少人说了实话。
  • 题解:二分图最大匹配
  • 首先,因为学生数小于等于 60, 所以如果排名区间差值大于60的,可以确保这个学生一定是可以说真话的,最后再来处理。对于区间小于等于 60 的,每个学生作为左边的点,右边的点就是区间 ( X i , X i + 1 , X i + 2 , . . . , Y i ) (X_i,X_{i+1},X_{i+2},...,Y_i) (XiXi+1Xi+2...Yi),两两连边,因为数字比较大,这里需要做一层离散化,先把所有区间按照值枚举出来,然后哈希到一个相对较小的下标中。然后,建立二分图求最大匹配。
  • 输出路径的时候需要保证字典序最大,只要保证匹配的时候从后往前枚举即可。

三、最小顶点覆盖

  • 二分图最小顶点覆盖 = 二分图最大匹配

HDU 1054 Strategic Game

  • 链接:HDU 1054 Strategic Game
  • 题意:在一棵树上,选择某些顶点就可以覆盖和它相连的边,求选取最小的顶点集合覆盖所有的边。裸最小顶点覆盖。

PKU 3041 Asteroids

  • 链接:PKU 3041 Asteroids
  • 题意: n ∗ n ( n < = 500 ) n*n (n <= 500) nn(n<=500) 的 01 矩阵上, 1的个数为 k ( k < = 1 0 5 ) k (k <= 10^5) k(k<=105),每次可以选择一整行消除整行的 1,或者一整列消除整列的 1,求选择最少的次数,将所有的 1 都消除。
  • 题解:二分图最小顶点覆盖
  • 将行作为二分图左边的点,列作为二分图右边的点,如果矩阵 A [ u ] [ v ] = 1 A[u][v] = 1 A[u][v]=1,则从左边的点 u u u 往右边的点 v v v 建立一条有向边 表示既可以通过选择行,也可以通过选择列来干掉这个 1。那么问题就变成了选择最少的顶点集合(行列集合),使得所有的边都被这些点集覆盖,转化成 二分图最小顶点覆盖 问题求解。

HDU 2119 Matrix

PKU 2226 Muddy Fields

  • 链接:PKU 2226 Muddy Fields
  • 题意:给定 R × C ( 1 < = R < = 50 , 1 < = C < = 50 ) R \times C(1 <= R <= 50, 1 <= C <= 50) R×C(1<=R<=50,1<=C<=50) 的 01 矩阵。希望选择一些 w × 1 w \times 1 w×1(横着) 或者 1 × h 1 \times h 1×h (竖着)的块,把所有的 1 都覆盖住(允许重复覆盖,但是不能覆盖到 0),求最少需要选择的区域。
  • 题解:二分图最小顶点覆盖
  • 将所有横着的连续块放到一个集合 X,所有竖着的连续块放到一个集合 Y;
  • 然后遍历集合 X,对所有 Y 里的做相交操作,如果第 u u u 个 X集合里的块 和 第 v v v 个 Y 集合里的块相交,则在图上建立一条 u → v u \to v uv 的边,那么每条边代表了一个 01 矩阵上的 1。
  • 问题转化为选择最少的块,覆盖所有这些边,即 二分图的最小顶点覆盖 问题。

HDU 1150 Machine Schedule

  • 链接:HDU 1150 Machine Schedule
  • 题意:有两个机器 A 和 B,机器 A 有 n n n 种工作模式,称为 m o d e [ 0 , . . . n − 1 ] mode[0,...n-1] mode[0,...n1];机器 B 有 m m m 种工作模式,称为 m o d e [ 0 , . . . m − 1 ] mode[0,...m-1] mode[0,...m1]。一开始他们都在 m o d e [ 0 ] mode[0] mode[0] 上工作,对于给定的 k k k 个作业,每一个作业都可以在这两台机器中的任意一台上以特定的模式进行处理。对于作业 i i i,约束可以表示为三元组 ( i , x , y ) (i, x, y) (i,x,y),这意味着它既可以在机器 A 的 m o d e [ x ] mode[x] mode[x] 处理,也可以在机器 B 的 m o d e [ y ] mode[y] mode[y] 处理。显然,为了完成所有的工作,我们需要不时地改变机器的工作模式,但不幸的是,机器的工作模式只能通过手动重启来改变。通过改变作业的顺序,并将每个作业分配给合适的机器,请编写一个程序,以减少重新启动机器的时间。
  • 题解:二分图最小顶点覆盖
  • 机器 A 作为左边的点, 机器 B 作为右边的点,对于所有的 ( x , y ) (x,y) (x,y),如果存在其中一个为 0,则不用管,直接完成;否则,建立一条 x → y x \to y xy 的有向边,那么只要选择其中一个点,对应的边就被覆盖了,每条边代表一个任务,所有任务都需要完成;
  • 问题转化成选择最少的点,覆盖所有这些边,即 二分图的最小顶点覆盖 问题。

HDU 1498 50 years, 50 colors

  • 链接:HDU 1498 50 years, 50 colors
  • 题意:给定 n ∗ n ( n < = 100 ) n * n(n <= 100) nn(n<=100) 的格子,每个格子是 [ 1 , 50 ] [1,50] [1,50]的整数,问每次可以选择整行或者整列对数字进行消除,进行 k k k 次消除后,有哪些数字是一定不能被消除干净的。
  • 题解:枚举 + 二分图最小顶点覆盖
  • 枚举每个数字 r ( 1 < = r < = 50 ) r(1<=r<=50) r(1<=r<=50),然后枚举所有的格子,如果这个格子上的数字等于 r r r,那么对行到列建边,代表可以选择行,或者可以选择列对这个数字进行消除,问题转化成选择最少的行列,消除所有这些数字,即 二分图的最小顶点覆盖 问题。

HDU 1281 棋盘游戏

  • 链接:HDU 1281 棋盘游戏
  • 题意:对一个 n ∗ m ( n , m < = 100 ) n*m(n,m <=100) nm(n,m<=100) 的棋盘,在格子里放尽量多的一些国际象棋里面的“车”,并且使得他们不能互相攻击,并且限制了只有某些格子才可以放,而且在保证尽量多的“车”的前提下,棋盘里有些格子是可以避开的,也就是说,不在这些格子上放车,也可以保证尽量多的“车”被放下。但是某些格子若不放子,就无法保证放尽量多的“车”,这样的格子被称做重要点。请问有多少个重要点。
  • 题解:枚举 + 二分图最小顶点覆盖
  • 先按照 PKU 3041 Asteroids 的方法求出整个图的最小顶点覆盖 M。然后枚举每个可以放置棋子的点不选择的情况,然后对其它所有点求最小顶点覆盖 M’,如果 M’ < M,那么这个点就是重要点。

HDU 1045 Fire Net

  • 链接:HDU 1045 Fire Net
  • 题意:给定一个 n ∗ n n*n nn 的棋盘,黑白格子组成,白色格子可以放置棋子,黑色格子不能放置棋子,如果一行或者一列上有其它棋子,并且中间没有任何黑色格子,那么这样的放置是非法的,求尽量放置最多的棋子(类似国际象棋中的 “车”)。
  • 题解:二分图最小顶点覆盖
  • 首先将棋盘进行行分块,如下:
  • 再进行列分块,如下:
  • 那么我们发现,任何一个格子都属于 一个行分块 和 一个列分块,假设一格格子 ( r , c ) (r,c) (r,c),它的行分块编号为 x x x,列分块编号为 y y y,每个能够放置棋子的点一定是要么行分块要么列分块来决定的。那么,我们把每个能够放置棋子的点看成是二分图的边,即建立边 : x → y x \to y xy,选择最少的点覆盖所有的边,就相当于把所有的格子上的位置都占据满了。
  • 于是,转换成最小顶点覆盖问题求解。

HDU 5093 Battle ships

HDU 2236 无题II

  • 链接:HDU 2236 无题II
  • 题意:在一个 n ∗ n ( n < = 100 ) n*n (n <= 100) nn(n<=100) 的矩阵中,找 n n n 个数 x ( 0 < = x < = 100 ) x(0<=x<=100) x(0<=x<=100) 使得这 n n n 个数都在不同的行和列里并且要求这 n n n 个数中的最大值和最小值的差值最小。
  • 题解:二分枚举 + 二分图最小顶点覆盖
  • 首先二分一个答案 r r r,然后枚举最小值 x x x,那么所有被选择的数字必须满足在 [ x , x + r ] [x, x+r] [x,x+r] 范围内,然后就转化成了选择最少的行列,使得这些数都能被选到了,即 二分图的最小顶点覆盖 问题。时间复杂度 O ( n 3 l o g n ) O(n^3logn) O(n3logn)

HDU 3360 National Treasures

  • 链接:HDU 3360 National Treasures
  • 题意:如图所示,在一个博物馆内,如果在 X 标记的地方放入一个雕像,那么其它 12 个位置必须放置守卫。那么给定几个雕像的位置,问至少要替换掉多少雕像(雕像可以改成守卫),才能满足条件使得所有的雕像都能被守住。
  • 题解:二分图最小顶点覆盖
  • 把有雕像的位置找出来,然后对这 12 个位置建边(如果位置上有守卫则不需要建),可以证明这一定是一个二分图。那么问题就转变成了,选择最少的点(变成守卫)从而将这些边都覆盖住,转换成 最小顶点覆盖。

HDU 6178 Monkeys

  • 链接:HDU 6178 Monkeys
  • 题意:给定一棵 n ( n < = 1 0 5 ) n(n <= 10^5) n(n<=105) 个结点的树,以及 k ( k < = n ) k(k <= n) k(k<=n) 只猴子,每个结点上可以放置至多一只猴子,现在需要去掉一些树边,使得每只猴子至少和另一猴子有边相连,求剩下的最小树边。
  • 题解:二分图最大匹配
  • 首先,树一定是二分图。可以先对这棵树求一次二分匹配,得到匹配数 M,然后进行分情况讨论;
  • 1) M ∗ 2 > = K M * 2 >= K M2>=K,那么很显然,可以选择这些匹配边两端放置这 K 只猴子,当 K 为偶数时,最小边数为 K / 2;K 为奇数时,最小边数为 ( K + 1 ) / 2 (K+1)/2 (K+1)/2
  • 2) M ∗ 2 < K M * 2 < K M2<K,其中 M ∗ 2 M * 2 M2 只猴子用去 M M M 条边,剩下 K − M ∗ 2 K-M*2 KM2 只猴子每个占用一条边,最小边数为 M + K − M ∗ 2 = K − M M + K - M * 2 = K-M M+KM2=KM
  • 注意由于数据量较大,这里求解的时候不能用匈牙利算法,需要用 树形 DP 求解。
#pragma   comment(linker, "/STACK:1024000000,1024000000")
int dp_[VMAX][2];          // 利用树形DP求树的最大匹配
                           // 0 以当前结点为父结点,和子结点之间没有匹配边
                           // 1 以当前结点为父节点,和子结点有一条匹配边(也顶多一条了)

四、最大独立集

HDU 1068 Girls and Boys

  • 二分图的最大独立集 = 总顶点数 - 最小顶点覆盖
  • 链接:HDU 1068 Girls and Boys
  • 题意:在学校里,给定一些男孩和女孩的关系图,求一个最大的集合,使得所有选出来的孩子之间都没有关系。
  • 题解:最大独立集的裸题。求出最大匹配后,用总的点数减去即可。

HDU 2768 Cat vs. Dog

  • 链接:HDU 2768 Cat vs. Dog
  • 题意:给定一些投票,格式如下: ( C a t i , D o g j ) (Cat_i, Dog_j) (Cati,Dogj) 代表留下 i i i 号猫,放弃 j j j 号狗,或者 ( D o g i , C a t j ) (Dog_i, Cat_j) (Dogi,Catj) 留下 i i i 号狗,放弃 j j j 号猫。需要选出最大的一个投票集合,使得所有的选择都不冲突;
  • 题解:最大独立集
  • 对于三种投票 A、B、C,可以推导出:如果 A 和 B 冲突,B 和 C 冲突,那么 A 和 C 一定不冲突,所以这是一个二分图,那么对于冲突的两个投票建边,然后求最大独立集合即可。

HDU 2458 Kindergarten

  • 链接:HDU 2458 Kindergarten
  • 题意: n n n 个男孩之间都有关系, m m m 个女孩之间也都有关系,某些男孩和某些女孩之间有关系,现在需要挑出一些孩子集合,使得所有的孩子都相互有关系,求集合最大值。
  • 题解:最大完全子图
  • 首先建立补图,然后问题转换成挑出一些孩子集合,两两之间都没有关系(这时候男孩子和那孩子之间,女孩子和女孩子之间都没有关系了),于是转变成二分图最大独立集问题求解。

五、最小边覆盖

PKU 3020 Antenna Placement

  • 二分图的最小边覆盖 = 总顶点数 - 孤立点数 - 最大匹配
  • 链接:PKU 3020 Antenna Placement
  • 题意:给定一个图由 ‘o’ 和 ’ * ’ 组成,每次可以选择 1 x 2 或者 2 x 1 的格子去覆盖 ’ * ',且允许重复覆盖,问最少需要选择的格子数。
  • 题解:对于任意一个 ’ * ’ 格子,检测四个相邻方向,是否也是 ’ * ’ 格子,如果是则建立一条边。那么问题就转变成,选择最少的边,覆盖所有 ’ * ’ 的格子。转化成就二分图最大匹配。

PKU 2724 Purifying Machine

  • 链接:PKU 2724 Purifying Machine
  • 题意:给定一些串,包含 0 、 1 、 ∗ 0、1、* 01 三种字符,其中 ∗ * 既可以代表 0 也可以代表 1,每次可以用一个模式匹配串 “???*???” 去匹配这些字符串然后从集合中去除,问最少需要多少个模式串才能完全取出集合中的元素。这里的模式串这么表示的意思是这个串中至多出现一个 ∗ * ? ? ? 代表的是确定的 0 或 1。
  • 题解:将带有 ∗ * 的串拆成两个,然后对所有拆好的串看成是点,任意两个串之间如果只有一位不同则连一条边,然后就是要求最少的边去覆盖所有的点,求二分图最大匹配即可。
  • 注意:由于待匹配模式的输入,可能导致出现重复点,可以先哈希一次去重。

六、最小路径覆盖

HDU 1151 Air Raid

  • 二分图的最小路径覆盖 = 总顶点数 - 拆图后的二分图最大匹配
  • 链接:HDU 1151 Air Raid
  • 二分图最小不相交路径覆盖 模板题。

HDU 1350 Taxi Cab Scheme

  • 链接:HDU 1350 Taxi Cab Scheme
  • 题意:输入给定 n ( n < = 500 ) n(n <= 500) n(n<=500) 个订单,每个订单一个时间 t t t,以及 a 、 b 、 c 、 d a、b、c、d abcd 四个数,代表一辆出租车从 t t t 时刻开始,从 ( a , b ) (a,b) (a,b) 开到 ( c , d ) (c,d) (c,d),两点间花费的时间为两者曼哈顿距离,即:
    ∣ a − c ∣ + ∣ b − d ∣ |a-c| + |b-d| ac+bd
  • 每个订单时刻递增排序给出,如果第 i i i 个订单送完以后能够在前一分钟到达第 j j j 个订单的起点,那么认为可以由一辆出租车接单,问最少需要多少俩出租车才能完成这么多订单。
  • 题解:对于两个订单 i i i 和 订单 j j j,判断时间和距离,如果满足就建立一条边,然后对这个图求最小路径覆盖。

PKU 2594 Treasure Exploration

  • 链接:PKU 2594 Treasure Exploration
  • 题意:给定一张有向图,求它的最小可相交路径覆盖。
  • 题解:对原图每个顶点 u u u 求一次深搜 floodfill 建立从 u u u 顶点到其他点的传递闭包,然后求最小路径覆盖。

PKU 3216 Repairing Company

  • 链接:PKU 3216 Repairing Company
  • 题意:给定一些任务,每个任务三个参数 ( p , t , d ) (p, t, d) (p,t,d) 代表 地点、任务开始时间、任务持续时间,然后再给定一张双向图,表示两个地点之间的距离。问最少需要派多少个人才能完成所有这些任务。
  • 题解:首先对双向图进行一次 Floyd 计算任意两点见的最短路。然后对任意两个任务进行遍历,如果一个任务完成时间小于等于另外一个任务的开始时间则建立一条边,然后求最小路径覆盖。

猜你喜欢

转载自blog.csdn.net/WhereIsHeroFrom/article/details/112505491
今日推荐