BestCoder Round #60.1003.GT and set/HDU5506 dfs

GT and set

 
 Accepts: 35
 
 Submissions: 194
 Time Limit: 2000/1000 MS (Java/Others)
 
 Memory Limit: 65536/65536 K (Java/Others)
问题描述
NN个集合,每个集合中有A_iAi​​个数。
你要将这NN个集合划成LL个部分,使得每个部分的集合至少有一个共有的数。
如果至少有一个解输出YESYES,否则输出NONO
输入描述
第一行一个数T表示数据组数。(TT\leq2020)

对于每一组数据:
第一行两个数NN和LL。
接下来NN行每行描述一个集合:
第一个数A_iAi​​表示该集合的大小,之后xx个互不相同的整数表示该集合的元素。
集合里的数字都是正整数且不大于300300.

1\leq1NN\leq3030,1\leq1L\leq5L5,1\leq1A_iAi​​\leq1010,1 \leq L \leq N1LN

hack时建议输出最后一行的行末回车;每一行的结尾不要输出空格。
输出描述
对于每组数据输出一行YESYES或NONO
输入样例
2
2 1
1 1
1 2
3 2
3 1 2 3
3 4 5 6
3 2 5 6
输出样例
NO
YES
Hint
对于第二个样例,有三个集合{1 2 3},{4 5 6},{2 5 6} 你要划成两个部分。
有一种方案是把第二个和第三个集合划成一个部分,第一个在另一个部分。有一种方案是把第二个和第三个集合划成一个部分,第一个在另一个部分。 第二个和第三个集合的数字有一个交集{6},所以合法。
还有一种划分方案就是把第一个和第三个集合划成一个部分,第二个在另一个部分。

///1085422276
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<cmath>
#include<map>
#include<bitset>
#include<set>
#include<vector>
using namespace std ;
typedef unsigned long long ll;
#define mem(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,127,sizeof(a));
#define memfy(a)  memset(a,-1,sizeof(a));
#define TS printf("111111\n");
#define FOR(i,a,b) for( int i=a;i<=b;i++)
#define FORJ(i,a,b) for(int i=a;i>=b;i--)

#define inf 100000000
inline ll read()
{
    ll x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}
//***************************************
#define maxn 33
bool flag,vis[maxn];
int num[maxn],n,A,L;
bitset<301> S[maxn],tmp,temp,aa[maxn];

void dfs(int x)
{

      if(x==n+1)
      {
          flag=1;
          for(int i=1;i<=L;i++)
          {
              if(!num[i])flag=0;
          }
          return ;
      }
        if(flag)return ;
      for(int i=1;i<=L;i++){
        temp=aa[i];
          tmp=aa[i]&S[x];
          if(tmp.count()!=0)
          {
              aa[i]=tmp;
              num[i]++;
              dfs(x+1);
              num[i]--;
              aa[i]=temp;
          }
      }

}
int main()
{

    int T=read();
    while(T--)
    {
        scanf("%d%d",&n,&L);
        mem(vis);mem(num);
        FOR(i,1,30){
            S[i].reset();aa[i].set();
        }
        FOR(i,1,n){
            scanf("%d",&A);
            FOR(j,1,A){
                int x=read();
                S[i].set(x);
            }
        }
    //    for(int i=1;i<=6;i++)cout<<S[3][i];
        flag=0;
        dfs(1);
        if(flag){
            cout<<"YES"<<endl;
        }
        else{
            cout<<"NO"<<endl;
        }
    }
    return 0;
}
代码

 

posted @ 2015-10-21 18:28  meekyan  阅读(332)  评论(0编辑  收藏  举报