hdu 2208(dfs)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2208

思路:应用了并查集的思想,具体见注释;

View Code
 1 #include<iostream>
 2 const int MAXN=14;
 3 using namespace std;
 4 bool map[MAXN][MAXN];
 5 int root[MAXN];
 6 int N,M;
 7 
 8 //n为当前的点,m为目前的气球数目
 9 bool dfs(int n,int m){
10     if(m>M)return false;
11     if(n==N)return true;//搜到的最大的点为n-1;
12     for(int i=0;i<n;i++){
13         if(root[i]!=i)continue;//找每个集合的根
14         bool flag=true;
15         for(int j=i;j<n&&flag;j++){
16             if(root[j]==i)flag=map[j][n];//必须保证集合里的所有的小盆友都不冲突
17         }
18         if(flag){
19             root[n]=i;//可以加入集合,合并
20             if(dfs(n+1,m))return true;
21             root[n]=n;//也可以不加入
22         }
23     }
24     if(dfs(n+1,m+1))return true;//如果都不满足要求,则搜下一个小盆友,气球数目增加
25 }
26 
27 int main(){
28     while(~scanf("%d%d",&N,&M)){
29         memset(map,false,sizeof(map));
30         for(int i=0;i<N;i++){
31             int k,x;
32             scanf("%d",&k);
33             for(int j=0;j<k;j++){
34                 scanf("%d",&x);
35                 map[i][x]=true;
36             }
37         }
38         for(int i=0;i<N;i++)root[i]=i;
39         if(N<=M||dfs(0,0)){
40             printf("YES\n");
41         }else 
42             printf("NO\n");
43     }
44     return 0;
45 }

 

 

posted @ 2013-04-10 18:18  ihge2k  阅读(245)  评论(0编辑  收藏  举报