标签:
题目大意:男生和女生若存在浪漫关系,则不能分在同一组,要求找出最大的分组,使得两两之间都不存在浪漫关系。
这个题一开始直接用dfs加上剪枝,但无奈TLE。。后来学习了二分图、寻找最大匹配、匈牙利算法等相关知识,终于ac。
二分图:即顶点集可以分割为两个互不相交的子集,且子集内的顶点互不相邻。
最大匹配:二分图G的子图M中,M的任意两条边都不依附于同一个顶点,则M是一个匹配。
匈牙利算法:用增广路径求最大匹配,从二分图的左边顶点开始寻找匹配,若能找到则res+1;再匹配下一顶点,若右顶点已匹配则回溯上一顶点重新匹配,若成功res+1;重复以上步骤,直至遍历左边顶点。
二分图的一些性质:
最大独立集=|V|-最大匹配
最大匹配=最小顶点覆盖(即最少的顶点可覆盖所有边)
找最大不存在浪漫关系的分组,即找最大独立集。由于题目未标明男女生性别,所以将所有人都看作二分图的左边和右边,则匹配数为原来的两倍,最后要做相应处理。
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #define max 1000 5 6 int stu[max][max],visit[max],linker[max],n,num,i,j,k,res; 7 8 bool dfs(int i){ 9 int j; 10 for(j=0;j<n;j++){ 11 if(stu[i][j]==1&&visit[j]==0){ 12 visit[j]=1; 13 if(linker[j]==-1||dfs(linker[j])){ 14 linker[j]=i; 15 return true; 16 } 17 } 18 } 19 return false; 20 } 21 22 int main(){ 23 while(scanf("%d",&n)!=EOF){ 24 res=0; 25 memset(stu,0,sizeof(stu)); 26 memset(linker,-1,sizeof(linker)); 27 for(i=0;i<n;i++){ 28 scanf("%d: (%d)",&i,&num); 29 while(num){ 30 scanf("%d",&j); 31 stu[i][j]=1; 32 num--; 33 } 34 } 35 for(i=0;i<n;i++){ 36 memset(visit,0,sizeof(visit)); 37 if(dfs(i)) res++; 38 } 39 printf("%d\n",n-res/2); 40 } 41 return 0; 42 }
标签:
原文地址:http://www.cnblogs.com/daic/p/4857042.html