今天学习了下二分图,算是进来的比较新的一块内容了吧。
关于匈牙利算法之前也看过一些,但一直没怎么搞懂,今天看了个很好的博客,茅塞顿开啊。
一看就懂的匈牙利算法:http://blog.csdn.net/dark_scope/article/details/8880547
关于二分图的东西我也不是太懂(自行百度)。再说一些很专业的东西知道了也没什么用(假的),所以很多证明类的东西也不会,也就讲讲板子吧。
最大匹配:
匈牙利算法——这是整个二分图中最有用的算法了,也是最基本的算法。
主要是一个增广路的过程(我乱编的)。
每次寻找时,如果目标点还没被占用就直接连上。如果被占用了就把目标点和它之前相连的点的边先拆掉,再递归看看原来的匹配点有没有其它的目标点可供选择。
还是建议看上面的博客(实在是讲不清楚)
模板CODE
inline bool find(int now) { for (int i=head[now];i!=-1;i=e[i].next) if (!vis[e[i].to]) { vis[e[i].to]=1; if (!from[e[i].to]||find(from[e[i].to])) { from[e[i].to]=now; return 1; } } return 0; }
在主程序中只要(注意要清零vis数组,因为它是记录当次是否匹配成功的),最后ans就是最大匹配
for (i=1;i<=n;++i)
{ memset(vis,0,sizeof(vis)); ans+=find(i); }
关于二分图其它性质的东西(结论及证明等参考http://blog.csdn.net/flynn_curry/article/details/52966283)
概念:
最小顶点覆盖:用最少的点,让每条边都至少和其中一个点关联;
最小边覆盖:用尽量少的不相交简单路径覆盖有向无环图(DAG)G的所有顶点;
最大独立集:在N个点的图G中选出m个点,使这m个点两两之间没有边的点中,m的最大值。
结论:
(a)、对于不存在孤立点的图,最大匹配+最小边覆盖=顶点数;
(b)、最大独立集+最小顶点覆盖=顶点数;
二分图中:
(c)、最大匹配=最小顶点覆盖。
(其实像我这样的蒟蒻只用记记结论就好了,证明可以看上面的博客,讲的很详细)
另外有些板子题:
Luogu 3386:二分图最大匹配的板子题;
POJ 3041:最小顶点覆盖的板子题;
POJ 3020:最小边覆盖的板子题;