正题
好久没有更过算法了。
二分图嘛,就是左边一堆独立的点,右边一堆独立的点,左右相连。
就是一个简单的二分图。
简单的二分图匹配可以用绿与被绿匈牙利算法来解决。
也就是说拼命的抢走之前匹配过的点,然后使自己空出来。
很好理解,代码如下。
bool dfs(int x,int k){
if(vis[x]==k) return 0;
vis[x]=k;
for(int i=first[x];i!=0;i=s[i].next){
int y=s[i].y;
if(last[y]==0 || dfs(last[y],k)){
last[y]=x;
return 1;
}
}
return 0;
}
接着我们来讲讲几个关于二分图匹配定理的证明。
1.最小覆盖点=最大匹配
其实可以想象,如果m为最大匹配,那么至少有m个点来把他们所对应的边全部覆盖。
而且,这个东西小于等于m,因为一条匹配的两个端点只能有一个有其他匹配的边,否则,匹配数会+1.
所以我们只要选择一个匹配中有多边的一个点就可以了。
肯定是m。
2.最小边覆盖=顶点数-最小点覆盖(最大匹配)
这个很好证,我们设顶点数是n,最小点覆盖是m,那么我们的最好的方法就是让每个匹配覆盖两个点,越大越好,那么就是最大匹配,覆盖的点数是2*m,我们把剩下来的设为a,那么2*m+a=n,总共用了m+a.那么ans=m+a=(2*m+a)-m=n-m,即为顶点数-最小点覆盖。
3.最大独立集+最小点覆盖=顶点数
因为独立集的定义就是使得点与点之间不联通,又因为匹配的两个端点只有一边是连接多条边的,所以我们先选另一边,那么不选的就只有那些在匹配里,而且连着多条边的点(就是不选最小点覆盖)。剩下的一定不联通,好好想想。
所以整张都利用了“一个匹配只有一个端点可能有多条出边”这个定理。