HDU 1068

题目大意:男生和女生若存在浪漫关系,则不能分在同一组,要求找出最大的分组,使得两两之间都不存在浪漫关系。

这个题一开始直接用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 }

 

posted @ 2015-10-06 13:38  生长努力的菜  阅读(241)  评论(0编辑  收藏  举报