唉,可爱的小朋友

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ACM__dongsheng/article/details/50791842

Problem Description

唉,小朋友是比较麻烦的。在一个幼儿园里,老师要上一节游戏课,有N个小朋友要玩游戏,做游戏时要用小皮球,但是幼儿园里只有M个小皮球,而且有些小朋友不喜欢和一些小朋友在一起玩,而只喜欢和另一些小朋友一起玩,比如傻妞只喜欢和傻瓜,傻根,傻蛋们一起玩,傻根又不喜欢和傻蛋一起玩,傻蛋喜欢和傻子一起玩。所以老师只好把他们分组,每个组至少有一个小球可以玩,而且每个组内不会有两个小朋友,相互不喜欢。现在给你这样一个幼儿园里小朋友之间关系的描述,做为老师,是否可以上好这节游戏课。

Input

数据有多个case,每个case先输入两个值N(1<=N<=10)和M(1<=M<=10),表示有N个小朋友(从0到N-1标号),和M个小皮球。接着有N行,第i行先输入一个K(0<=K

这里写代码片
#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;

int n,m,map[20][20];
int root[20],flag;

void DFS(int x,int y){  x 人数,y 球数
    if(flag)   //满足方案
        return ;
    if(y>m)    //皮球数量超
        return ;
    if(x==n){   //皮球数量未超,人数达到目标;
        flag=1;
        return ;
    }
    for(int i=0;i<x;i++){
        if(root[i]!=i)  //找到一个集合,寻到根节点
            continue;
        int tag=1;
        for(int j=i;j<x && tag;j++) 
            if(root[j]==i)//找到根节点下的节点,判断是否和人喜欢
                tag=map[j][x];
        if(tag){    //喜欢
            root[x]=i;  //x指向根i;
            DFS(x+1,y); //人数加一,进入下个递归。
            root[x]=x; //将该点还原,以找到下一个该点的可能落脚点,以确保可以考虑到所有的可能
        }
    }
    DFS(x+1,y+1);
}

int main(){
    while(~scanf("%d%d",&n,&m)){
        memset(map,0,sizeof(map));
        flag=0;
        int k,x;
        for(int i=0;i<n;i++){
            scanf("%d",&k);
            root[i]=i;
            while(k--){
                scanf("%d",&x);
                map[i][x]=1;    
            }
        }
        DFS(1,1);
        if(m>=n || flag)
        cout<<"YES"<<endl; 
        else
            cout<<"NO"<<endl; 
    }
    return 0;
}
展开阅读全文

没有更多推荐了,返回首页