二分图总结
arc[h][v]//建立边 arc[h][0]指的是h点的边数,arc[h][1]开始是h指向的点 int arc[510][510]; int link[510]; bool use[510]; int h,v; bool find_max(int s) { for(int j=1;j<=arc[s][0];++j) { int i=arc[s][j]; if(!use[i]) { use[i]=1; if(link[i]==-1||(link[i]!=-1&&find_max(link[i]))) { link[i]=s; return 1; } } } return 0; } int find() { int num=0; memset(link,0xff,sizeof(int)*v); for(int i=0;i<h;++i) { memset(use,0,sizeof(bool)*v); if(find_max(i)) ++num; } return num; }
如果一个图的顶点可以分为两个集合X和Y,图的所有边一定是有一个顶点属于集合X,另一个顶点属于集合Y,则称该图为“二分图”( Bipartite Graph )
对于图 G=(V,E),如果E∈C使得对于任意的 v∈V,都关联于 C 中的一条边,则
称 C 为图 G 的一个覆盖(原图所有边都关联C边集合所关联的点)。图 G 的边数最少的覆盖称为 G 的最小覆盖。
二分图的最小覆盖=最大二分匹配
图G中两两互不相邻的顶点构成的集合称为最大独立集
二分图最大独立集=h+v-最小覆盖数
最大二分匹配问题
COURSES poj1469
给出n个学生对p个课程的爱好,每个课程只有一个名额。求能否安排满所有的课程
完全裸的二分匹配。求二分匹配后判断是否二分匹配数是否与p相等。
Sorting Slides poj 1486
求二分图的唯一最大匹配边。即这个二分图不管怎么建立最大二分匹配图都含有要求的边。
先求最大分配,对于每一对,判断它是否唯一,只需把匹配的边先删除后,再求最大匹配,如果匹配数=n-1,则此匹配边唯一。
Place the Robots
在一个有墙,草地,空地的地图上放置机器人,放置最多的机器人且使得它们不互相攻击。
考虑没有墙,没有草的情况,我们直接横坐标与纵坐标作为二分图的两边并且两两建立边,求最大的二分匹配就可以。放置机器人的位置即为边 i,j;
有了草地和墙后其实也不难,现在就只有空地可以放机器人了。我们先计算没穿越石头的连续横块和竖块。分别放在二分图的两边x,y。然后若x,y中的边相交且交点为空地,则建立边。
然后求二分匹配。
最小覆盖问题
Machine Schedule
有A,B两台机,每台机各自有n,m种模式,
现在有工作 i,它可以在 A以 a模式运行或在B中以b模式运行
现在要求最少的重启次数使得所有工作运行。所以问题就转换为求二分图的最小覆盖。
注意0模式的时候不需要考虑,因为0 不需要重启。
Strategic Game
求一棵无向树,选择最少的点,使得这些点能关联其它所有点。
将每个点拆分成在两边,可视为出点和入点。求最小覆盖,即求出了覆盖出口点和入口点的最小方案,除以2即得出了最小覆盖所有原顶点的方案。
注意只有无向图才可以这种方法计算最小覆盖。
Air Raid
求一棵有向树,选择最少的点,使得这些点能访问到其它所有点。
同样将点拆分在两边,可视为出点和入点。求最大匹配,即求出了出点最多能覆盖哪些点(最大匹配的性质一个出点只能覆盖一个入点,符合题意单向无回路的性质),则这些点可以不用派人去。由出点送人过去就行。所以答案=n-最大匹配
推广之就是求有向树的最小覆盖,为什么是有向树?如果带环的话,
1使得3可以不派人
3使得2可以不派人
2使得1可以不派人
这就产生了一个死循环了。答案自然错。
所以有环有向图 不能用二分图求最小覆盖。
最大独立集问题
Girls and Boys http://poj.org/problem?id=1466
题意:给出男女关系,求没关系的男女的最大集合。
由于只有男跟女有关系,所以他们的关系可以用一个二分图表示
题目就转换为求一个二分图的最大独立集。
由于具体性别没有给出。我们不管男女分成两边一起求的话,求出最小覆盖是分成两边的两倍。
所以答案=n-num/2
Wrong Answer BAPC 2010
题意:水平给出一些字符串,垂直给出一些字符串,求去掉最少的字符串使得他们的其它所有字符串都不互相影响。
例如这个图 去掉 BAPC后是最好的方案。
将水平方向和垂直方向的字符串分在二分图的两边。若两个字符串相交,且相交点为不同字符,则两字符串建立联系。问题就转换为求二分图的最大独立集。答案就为 h+v-最小覆盖