您的位置:首页 > 其它

二分图匹配(匈牙利算法)

2014-08-16 10:55 218 查看
1。一个二分图中的最大匹配数等于这个图中的最小点覆盖数
König定理是一个二分图中很重要的定理,它的意思是,一个二分图中的最大匹配数等于这个图中的最小点覆盖数。如果你还不知道什么是最小点覆盖,我也在这里说一下:假如选了一个点就相当于覆盖了以它为端点的所有边,你需要选择最少的点来覆盖所有的边。
2。最小路径覆盖=最小路径覆盖=|G|-最大匹配数

 在一个N*N的有向图中,路径覆盖就是在图中找一些路经,使之覆盖了图中的所有顶点,

 且任何一个顶点有且只有一条路径与之关联;(如果把这些路径中的每条路径从它的起始点走到它的终点,

 那么恰好可以经过图中的每个顶点一次且仅一次);如果不考虑图中存在回路,那么每每条路径就是一个弱连通子集.
由上面可以得出:
 1.一个单独的顶点是一条路径;

 2.如果存在一路径p1,p2,......pk,其中p1 为起点,pk为终点,那么在覆盖图中,顶点p1,p2,......pk不再与其它的

   顶点之间存在有向边.
最小路径覆盖就是找出最小的路径条数,使之成为G的一个路径覆盖.
 路径覆盖与二分图匹配的关系:最小路径覆盖=|G|-最大匹配数;
3。二分图最大独立集=顶点数-二分图最大匹配
独立集:图中任意两个顶点都不相连的顶点集合。
4。最大独立集基数  =  最小点覆盖基数  =  总点数  -  最大匹配数基数。

模板
#include <stdio.h>
#include <string.h>

int map[1005][1005];
int zt[1005],link[1005];
int n,m;

//匹配边=未匹配边-1

int dfs(int u)
{
int i,j,k;
for(i=0;i<n;i++)//循环遍历,查找下一个
{
if(map[u][i] && zt[i]==0 && u!=i)//此次dfs右集合点有没有被查找
{
zt[i]=1;
if(link[i]==-1 || dfs(link[i]))//递归的出口都是找到未匹配
{
link[i]=u;
return 1;
}
}
}
return 0;//没找到未匹配的点
}

int main()
{
int i,j,k,a,b,c;
while(scanf("%d",&n)!=EOF)
{
memset(map,0,sizeof(map));
for(i=0;i<n;i++)
{
scanf("%d: (%d)",&b,&m);
for(j=0;j<m;j++)
{
scanf(" %d",&a);
map[b][a]=1;
}
}

for(i=0;i<1005;i++)
{
link[i]=-1;
}

int sum=0;
for(i=0;i<n;i++)
{
memset(zt,0,sizeof(zt));
sum+=dfs(i);
}
//最大独立子集=总人数-最大匹配数
printf("%d\n",n-sum/2);//这里的最大匹配数把关系计算了俩遍,基数为最大匹配数/2
}
return 0;
}题目:

Description

the second year of the university somebody started a study on the romantic relations between the students. The relation “romantically involved” is defined between one girl and one boy. For the study reasons it is necessary to find
out the maximum set satisfying the condition: there are no two students in the set who have been “romantically involved”. The result of the program is the number of students in such a set. 

The input contains several data sets in text format. Each data set represents one set of subjects of the study, with the following description: 

the number of students 

the description of each student, in the following format 

student_identifier:(number_of_romantic_relations) student_identifier1 student_identifier2 student_identifier3 ... 

or 

student_identifier:(0) 

The student_identifier is an integer number between 0 and n-1, for n subjects. 

For each given data set, the program should write to standard output a line containing the result. 

 

Sample Input

 7
0: (3) 4 5 6
1: (2) 4 6
2: (0)
3: (0)
4: (2) 0 1
5: (1) 0
6: (2) 0 1
3
0: (2) 1 2
1: (1) 0
2: (1) 0

 

Sample Output

 5
2
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: