zoukankan      html  css  js  c++  java
  • 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表示数据组数。(TTleq2020)
    
    对于每一组数据:
    第一行两个数NN和LL。
    接下来NN行每行描述一个集合:
    第一个数A_iAi​​表示该集合的大小,之后xx个互不相同的整数表示该集合的元素。
    集合里的数字都是正整数且不大于300300.
    
    1leq1NNleq3030,1leq1Lleq5L5,1leq1A_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
    ");
    #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;
    }
    代码
  • 相关阅读:
    重载小于号
    无聊的会议
    程序内存和时间
    对拍
    读入和输出优化
    codevs 3269 混合背包
    清北第三套题
    codevs 2188 最长上升子序列
    清北第二套题
    [COGS896] 圈奶牛
  • 原文地址:https://www.cnblogs.com/zxhl/p/4898640.html
Copyright © 2011-2022 走看看