匹配主要就是二分图匹配和一般图匹配,一般图的带花树算法我还不会
二分图匹配主要就是匈牙利算法,也可以用最大流解决
具体的看blog:http://www.renfei.org/blog/bipartite-matching.html 讲的比较清楚了
今天做了几个简单题
hdu 1045
题意:给你个棋盘,一部分地方不能放,然后问你最多放多少个,同一行同一列不能有多个,不过如果两个同行或者同列之间隔着一个墙,就能放
题解:这题就是建图难,一开始想不到吧,可以把没有分开的一段行和列缩成一个点,然后如果这段行和某点列有相交部分,就是这两个点之间有边,然后最多放多少个棋子,就是最多取多少条边,就是二分图的最大匹配问题了
#include
hdu 2444
题意:给你一些朋友关系,然后问把他们分成两组,每组中都不是朋友,第一组中每个人在第二组中都有一个朋友,明显就是二分图的最大匹配,不过就是可能给你的图有环,问你能不能构成二分图
题解:就是首先判断是否是二分图,这个用染色算法,就是dfs,如果搜到一条边上两端颜色相同就显然不是二分图。
判断完是二分图之后直接就匈牙利上了
数组貌似比较恶心,要开的大一点
#include
hdu 1083
全裸的匈牙利一套带走
不说了
hdu 1281
题意:就是每行每列只能有一个车,然后有些点可以放车,不能放的点不影响(和第一题棋盘不同,我开头看错了)
重要点就是如果这个地方不放,那么就会影响最大数量
题解:有了第一题的经验,这题很明显就是行列缩成一个点,车所在的点就是行列相交的地方,就是行(点)和列(点)之间连接的边,然后墙壁不影响,更容易了,直接给你的坐标建图,然后先求出最大匹配,再枚举删除每条边,如果得到的匹配数不等于最大匹配,那么这个点就是重要点。
#include
hdu 2819
题意:给你一个01矩阵,问你能不能通过行列交换,使对角线都是1
题解:首先要知道,如果i行j列是1,那么就是点i->j+n有边,所以对角线都为1,就是说最多可以连n条边,就是最大匹配是n
把行和列缩点,求出最大匹配,如果是n,然后就是看交换多少次,要知道变成对角线为1,只用行变换或者只用列变换都可以做到,所以枚举每行,看对应的行match的是不是这一列,如果不是就找下面满足的行和它换(其实挺水的,一开始没认真做,题目都没怎么搞懂)
#include
hdu 2389
题意:就是给你6000个点,分成两堆,给你坐标,然后给你人的速度,如果在时间内这个人能跑到伞所在的坐标,那么这两个点之间就有边,这样的话最多有3000×3000的边
匈牙利就会TLE,用网络流的ISAP要建反向边1800W伤不起,所以就去学了HK算法,详见http://www.cnblogs.com/penseur/archive/2013/06/16/3138981.html
#include
题解:套一发模板就好了