二分图匹配
T1 DTOJ 2346. 小凸玩矩阵
题意
小凸和小方是好朋友,小方给了小凸一个n×m(n≤m)的矩阵A,并且要求小凸从矩阵中选出n个数,其中任意两个数都不能在同一行或者同一列。现在小凸想知道,选出的n个数中第k大的数的最小值是多少。
数据范围
对于100%的数据,1≤k≤n≤m≤250,1≤Ai,j≤109
题解
显然二分答案,判断ans是否 ≤ \le ≤x,即>ans的点不能超过k-1个。对于矩阵行列匹配的题考虑把行和列看作点,每个数看作边,然后为什么我想的就是直接费用流呢(最近怎么每道题都想到最麻烦的做法啊)。直接把 ≤ \le ≤ans的点连上,看最大匹配是否大于n-k个就好啦,因为是完全图剩下的一定能匹配完。
T2(DAG路径覆盖问题)
洛谷 4589 [TJOI2018]智力竞赛
题解
这题目描述无力吐槽,害我自闭了很久(虽然好像本来也确实不会)。
题意就是给一个m个点的DAG,求n条可相交的路径覆盖后,剩余的点的最小值的最大值。
首先显然二分答案,问题转化为有一些点一定要覆盖的最少可相交路径数。
先考虑一个DAG的点全部都覆盖的最少不相交路径数,首先如果每个点都作为一条路径的话就是n,考虑在此基础上合并一些路径。每个点拆为x,y,对于一条有向边 ( u , v ) (u,v) (u,v),连 ( u y , v x ) (uy,vx) (uy,vx),如果匹配这两个点,就说明把u结尾和v开头的路径合并在一起,于是匹配了多少就相当于合并了多少次,答案就是n-最大匹配。
然后是点可以相交的情况,考虑把相交的变为不交的,转化为上面的问题。对于任意u可以到达v,连一条有向边 ( u , v ) (u,v) (u,v),这样对于所有相交的点可以让其他路径跳过,一条路径保留。
对于特定的点,因为是路径可以相交的,直接按照上面做法把可以到达的关键点对连有向边即可。想了半天点不能相交怎么做,发现完全不会,那假装不可做了(不然题目就出了?)。
T3(费用流) DTOJ 4740. 校运会
题意
S S SS Z Z ZX 的校运会又开始了。
高一 X X X 班的同学们组成了一个由 n n n 名同学构成的代表队。运动会一共设 m m m 个运动项目,每名同学只能报名最多一个项目,每个项目每个班级也只能报名最多一名同学。
高一 X X X 班的体育委员收集了代表队所有名同学的期望参赛项目和预估参赛成绩。预估参赛成绩分为 K K K 档,从第 1 1 1 名到第 K K K 名。同学们只愿意参加上报的比赛项目。
体育委员把收集的数据交给了你,你需要提供一个报名方案,使得在满足比赛规则和同学要求的情况下,使获得第一名的选手最多。如果两个方案获得第一名的选手一样多,则希望获得第二名的选手最多。以此类推,直到第 K K K名。
对于 20 % 20\% 20% 的数据, 1 ≤ n , m ≤ 10 , 1 ≤ K ≤ 10 1\le n,m\le 10,1\le K\le 10 1≤n,m≤10,1≤K≤10.
对于另外 20 % 20\% 20% 的数据, K = 1 K=1 K=1.
对于 100 % 100\% 100% 的数据, 1 ≤ n , m ≤ 1000 , 1 ≤ K ≤ 10 , ∑ k i ≤ 10000 , 1 ≤ k i ≤ m , 1 ≤ x i j ≤ m , 1 ≤ y i j ≤ K 1\le n,m\le 1000,\, 1\le K\le 10,\,\sum{k_i}\le 10000,\, 1\le k_i\le m,\, 1\le x_{ij}\le m,\, 1\le y_{ij}\le K 1≤n,m≤1000,1≤K≤10,∑ki≤10000,1≤ki≤m,1≤xij≤m,1≤yij≤K.
题解
显然是二分图的模型,考场上想的是把边权按照1000进赋值,然后取跑费用流,但需要开两个long long存边权,写到自闭了。
其实考虑一下一个匹配被替换的时候,最多在左右两边的点各多一个匹配,而如果有排名由于原来匹配的肯定更优,否则最多就是两个排名多1的匹配,所以边权直接赋值为上一个*2+1即可。
注意本题应跑的是最大费用可行流,而不是最大流。
以及spfa等号的时候不要更新,会死循!!!
T4 BZOJ3140 消毒(二分图最小点覆盖)
题意
最近在生物实验室工作的小T遇到了大麻烦。
由于实验室最近升级的缘故,他的分格实验皿是一个长方体,其尺寸为abc,a、b、c 均为正整数。为了实验的方便,它被划分为abc个单位立方体区域,每个单位立方体尺寸
为111。用(i,j,k)标识一个单位立方体,1 ≤i≤a,1≤j≤b,1≤k≤c。这个实验皿已经很久没有人用了,现在,小T被导师要求将其中一些单位立方体区域进 行消毒操作(每个区域可以被重复消毒)。而由于严格的实验要求,他被要求使用一种特定 的F试剂来进行消毒。 这种F试剂特别奇怪,每次对尺寸为xyz的长方体区域(它由xyz个单位立方体组 成)进行消毒时,只需要使用min{x,y,z}单位的F试剂。F试剂的价格不菲,这可难倒了小 T。现在请你告诉他,最少要用多少单位的F试剂。(注:min{x,y,z}表示x、y、z中的最小 者。)
abc≤5000,T≤3。
题解
首先是前置知识(原本啥都不会想题直接自闭)
1.二分图最小点覆盖=二分图最大匹配
设二分图最大匹配为x,二分图最小点覆盖为y,首先显然
x
≤
y
x\le y
x≤y,考虑对于一条匹配边,它的两个端点不会都连向其他未匹配点(否则交换更优),所以定一个点为匹配点即可覆盖。
2.二分图最小边覆盖=点数-二分图最大匹配
每个点都先选,减掉每个最大匹配的一个端点,每条边的两个端点显然不会同时被选。
3 二分图最大独立集=点数-二分图最大匹配
去掉最小点覆盖的点后,每条边不会连接剩下的任意两个点,就是最大独立集了。
首先肯定是每次取一个面,发现如果是二维就是一个二分图最小点覆盖,而三维不太可做。注意到数据范围 a b c ≤ 5000 abc\le5000 abc≤5000,一定会有一维 ≤ 17 \le17 ≤17,枚举这一维每个面是否选,再做二分图匹配即可。
T5 CF981F(Hall定理)
题目链接
题解
前置知识(Hall定理):
设二分图两边的为
x
,
y
(
x
≤
y
)
x,y(x\le y)
x,y(x≤y) 一个二分图的最大匹配为:点数-
m
a
x
(
∣
S
∣
−
∣
T
∣
)
max (|S|-|T|)
max(∣S∣−∣T∣)其中S为x的任意子集,T为S连向的点集。
于是这题先二分答案x,然后判定在每个A点可以向周围x的距离的B点连边时,最大匹配是否为n。运用Hall定理,结合画图发现就是每一个连续的区间对应连边的集合不小于自己,列出式子记一下前缀最大值即可判断。注意是环上,所以A要复制一遍,B也跟随复制一遍,并且在头尾再复制一遍。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+5;
int n,m,k; ll a[N],b[N];
int cnt(ll x){
return upper_bound(b+1,b+k+1,x)-b-1;
}
bool chk(ll d){
//cout<<"d="<<d<<endl;
int mx=-N;
for(int i=1;i<=n;i++){
int x=cnt(a[i]+d)-i;
mx=max(mx,cnt(a[i]-d-1)-i);
//cout<<i<<" "<<x<<" "<<mx<<endl;
if(x<=mx) return 0;
}
return 1;
}
int main()
{
srand(time(0));
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
cin>>n>>m;
for(int i=1;i<=n;i++) scanf("%I64d",&a[i]);
sort(a+1,a+n+1);
for(int i=n+1;i<=n+n;i++) a[i]=a[i-n]+m;
for(int i=1;i<=n;i++) scanf("%I64d",&b[i+n]);
sort(b+n+1,b+n+n+1);
for(int i=1;i<=n;i++) b[i]=b[i+n]-m;
for(int i=n*2+1;i<=n*3;i++) b[i]=b[i-n]+m;
for(int i=n*3+1;i<=n*4;i++) b[i]=b[i-n]+m;
n<<=1; k=(n<<1);
int l=0,r=m/2;
while(l<r){
int mid=(l+r)>>1;
if(chk(mid)) r=mid;
else l=mid+1;
}
cout<<l<<endl;
return 0;
}
/*
10 100
98 61 9 46 52 8 82 32 14 23
27 18 46 51 74 98 61 84 22 73
*/
稳定婚姻匹配问题
T6 DTOJ 2134. 矩阵变换(matrix)
题意
给出一个 N 行 M 列的矩阵A, 保证满足以下性质:
-
M>N 。
-
矩阵中每个数都是 [0,N] 中的自然数。
-
每行中, [1,N] 中每个自然数都恰好出现一次。这意味着每行中 0 恰好出现 M−N 次。
-
每列中,[1,N] 中每个自然数至多出现一次。
现在我们要在每行中选取一个非零数,并把这个数之后的数赋值为这个数。我们希望保持上面的性质4,即每列中,[1,N] 中每个自然数仍然至多出现一次。
对于 100% 的数据,N<200,M<400,T<50 。
题解
先考虑比较特殊的位置,比如最后一列,就发现每行要选的数必须是互不相同的,即转化为求
1
−
n
1-n
1−n行与数
1
−
n
1-n
1−n的一个合法匹配。
设第
i
i
i行匹配的数为
p
i
p_i
pi,出现在
p
o
s
i
pos_i
posi列,考虑怎样的匹配合法。对于
a
i
,
j
a_{i,j}
ai,j,如果有一行
j
j
j,
p
[
j
]
=
a
[
i
]
[
j
]
p[j]=a[i][j]
p[j]=a[i][j],且
p
o
s
[
j
]
≤
j
pos[j] \le j
pos[j]≤j,这样如果
a
[
i
]
[
j
]
a[i][j]
a[i][j]没有该行被前面的数覆盖则不合法。
发现该限制是一个稳定婚姻匹配问题,直接做即可。
二分图博弈问题
T7 DTOJ 4339. 游戏
题意
小AA和小YY得到了《喜羊羊和灰太狼》的电影票,都很想去观看,但是电影票只有一张,于是他们用智力游戏决定胜负,赢得游戏的人可以获得电影票。
在 N ∗ M N*M N∗M 的迷宫中有一个棋子,小AA首先任意选择棋子放置的位置。然后,小YY 和小AA轮流将棋子移动到相邻的格子里。游戏的规则规定,在一次游戏中,同一个格子不能进入两次,且不能将棋子移动到某些格子中去。当玩家无法继续移动棋子时,游戏结束,最后一个移动棋子的玩家贏得了游戏。
例如下图所示的迷宫,迷宫中表示棋子可以经过的格子,而 “#” 表示棋子不可以经过的格子:
. # # .~\#~\# . # #
. . . .~.~. . . .
# . # \#~.~\# # . #
若小AA将棋子放置在 ( 1 , 1 ) (1,1) (1,1),则小AA则无论如何都无法赢得游戏。
而若小AA将棋子放置在 ( 3 , 2 ) (3,2) (3,2) 或 ( 2 , 3 ) (2,3) (2,3) ,则小AA能够贏得游戏。例如,小AA将 棋子放畀在 ( 3 , 2 ) (3,2) (3,2),小YY只能将它移动到 ( 2 , 2 ) (2,2) (2,2) ,此时小AA再将棋子移动到 ( 2 , 3 ) (2,3) (2,3), 就贏得了游戏。
小AA和小YY都是绝顶聪明的小朋友,且从不失误。小AA到底能不能赢得这场游 戏,从而得到珍贵的电影票
对于 100 % 100 \% 100% 的数据,有 1 ≤ n , m ≤ 100 1 \le n,m \le 100 1≤n,m≤100 。
对于 30 % 30 \% 30% 的数据, 有 1 ≤ n , m ≤ 5 1 \le n,m \le 5 1≤n,m≤5。
题解
比较套路地将格子黑白染色,相邻的连边,可以得到一个二分图,问题变成有哪些点可以从它出发沿着边走必胜。
由于在二分图上走交替路的过程和匈牙利算法相似,考虑二分图最大匹配。
先考虑特殊情况:如果存在完美匹配,则不管从哪个点出发,只要对方沿着匹配边走,你最多只能沿着非匹配边走到匹配点,然后对方再走匹配边,你早晚会死的。
否则,考虑把对方逼到这种局面:从任意一个非匹配点出发,对方只能走到匹配点(否则原来不是最大匹配),然后你沿着匹配边走,对方在走只能沿着非匹配边走到一个匹配点(如果可以走到非匹配点的话,把这条路径画出来,会发现匹配数可以增加),以此类推你就win了。
于是问题转化为求哪些点可能不在最大匹配中:先求出任意一个最大匹配,把非匹配点拿去寻找可能成为非匹配的点。考虑用它所连的非匹配边去替换,则通过非匹配边连向的匹配点对应的匹配点是可以被替换掉的,新产生一个可行点后继续更新,是一个dfs的过程。