二分图的一些总结
二分图最大匹配的匈牙利算法
二分图是这样一个图,它的顶点可以分类两个集合X和Y,所有的边关联在两个顶点中,恰好一个属于集合X,另一个属于集合Y。
最大匹配: 图中包含边数最多的匹配称为图的最大匹配。
完美匹配: 如果所有点都在匹配边上,称这个最大匹配是完美匹配。
最小覆盖: 最小覆盖要求用最少的点(X集合或Y集合的都行)让每条边都至少和其中一个点关联。可以证明:最少的点(即覆盖数)=最大匹配数
最小路径覆盖:
用尽量少的不相交简单路径覆盖有向无环图G的所有结点。解决此类问题可以建立一个二分图模型。把所有顶点i拆成两个:X结点集中的i和Y结点集中的i',如果有边i->j,则在二分图中引入边i->j',设二分图最大匹配为m,则结果就是n-m。
最大独立集问题:
在N个点的图G中选出m个点,使这m个点两两之间没有边.求m最大值.
二分图是这样一个图,它的顶点可以分类两个集合X和Y,所有的边关联在两个顶点中,恰好一个属于集合X,另一个属于集合Y。
最大匹配: 图中包含边数最多的匹配称为图的最大匹配。
完美匹配: 如果所有点都在匹配边上,称这个最大匹配是完美匹配。
最小覆盖: 最小覆盖要求用最少的点(X集合或Y集合的都行)让每条边都至少和其中一个点关联。可以证明:最少的点(即覆盖数)=最大匹配数
最小路径覆盖:
用尽量少的不相交简单路径覆盖有向无环图G的所有结点。解决此类问题可以建立一个二分图模型。把所有顶点i拆成两个:X结点集中的i和Y结点集中的i',如果有边i->j,则在二分图中引入边i->j',设二分图最大匹配为m,则结果就是n-m。
最大独立集问题:
在N个点的图G中选出m个点,使这m个点两两之间没有边.求m最大值.
如果图G满足二分图条件,则可以用二分图匹配来做.
最大独立集点数 = N - 最大匹配数
代码
1 #define N 202
2 int useif[N]; //记录y中节点是否使用
3 int link[N]; //记录当前与y节点相连的x的节点
4 int mat[N][N]; //记录连接x和y的边,如果i和j之间有边则为1,否则为0
5 int gn,gm; //二分图中x和y中点的数目
6 int can(int t)
7 {
8 int i;
9 for(i=1;i<=gm;i++)
10 {
11 if(useif[i]==0 && mat[t][i])
12 {
13 useif[i]=1;
14 if(link[i]==-1 || can(link[i]))
15 {
16 link[i]=t;
17 return 1;
18 }
19 }
20 }
21 return 0;
22 }
23 int MaxMatch()
24
25 {
26 int i,num;
27 num=0;
28 memset(link,0xff,sizeof(link));
29 for(i=1;i<=gn;i++)
30 {
31 memset(useif,0,sizeof(useif));
32 if(can(i)) num++;
33 }
34 return num;
35 }
2 int useif[N]; //记录y中节点是否使用
3 int link[N]; //记录当前与y节点相连的x的节点
4 int mat[N][N]; //记录连接x和y的边,如果i和j之间有边则为1,否则为0
5 int gn,gm; //二分图中x和y中点的数目
6 int can(int t)
7 {
8 int i;
9 for(i=1;i<=gm;i++)
10 {
11 if(useif[i]==0 && mat[t][i])
12 {
13 useif[i]=1;
14 if(link[i]==-1 || can(link[i]))
15 {
16 link[i]=t;
17 return 1;
18 }
19 }
20 }
21 return 0;
22 }
23 int MaxMatch()
24
25 {
26 int i,num;
27 num=0;
28 memset(link,0xff,sizeof(link));
29 for(i=1;i<=gn;i++)
30 {
31 memset(useif,0,sizeof(useif));
32 if(can(i)) num++;
33 }
34 return num;
35 }
算法的基本思想:
算法的思路是不停的找增广轨,并增加匹配的个数,增广轨顾名思义是指一条可以使匹配数变多的路径,在匹配问题中,增广轨的表现形式是一条"交错轨",也就是说这条由图的边组成的路径,它的第一条边是目前还没有参与匹配的,第二条边参与了匹配,第三条边没有..最后一条边没有参与匹配,并且始点和终点还没有被选择过.这样交错进行,显然他有奇数条边.那么对于这样一条路径,我们可以将第一条边改为已匹配,第二条边改为未匹配...以此类推.也就是将所有的边进行"反色",容易发现这样修改以后,匹配仍然是合法的,但是匹配数增加了一对.另外,单独的一条连接两个未匹配点的边显然也是交错轨.可以证明,当不能再找到增广轨时,就得到了一个最大匹配.这也就是匈牙利算法的思路.
版权声明:版权归作者WeiSteven所有,转载请注明!
作者:W.M.steve
出处:http://www.cnblogs.com/weisteve/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
出处:http://www.cnblogs.com/weisteve/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。