DFS-bitset-hdu5506-GT and set

来源:互联网 发布:蔡康永 马东 知乎 编辑:程序博客网 时间:2024/06/05 11:27

给定你一些集合,如果这些集合中有相等的数,那么就可以把这俩集合合并在一起,问你是否可以把这些集合合并成n个,
(合并的数比n小也小,相同的是可以分开的。)
方法,已经知道是dfs,但是没想到是这种对状态的dfs,每次保留上一次分配的状态,枚举当前的集合,
注意 回溯。
方法挺好用的。
https://vjudge.net/problem/HDU-5506

#include <iostream>#include <algorithm>#include <cmath>#include <vector>#include <string>#include <cstring>#include <bitset>#include <cstdio>using namespace std;/*bitset的使用。另外还有暴力的搜索。*/bitset<320>ans[32];int n;int d;int dfs(int tim,bitset<320>*a)//这是过去已经规划好的状态、{   if(tim==n) return 1;//寻找完毕;   bitset<320> t[32];   for(int i=0;i<d;i++)    t[i]=a[i];   for(int i=0;i<d;i++)   {  t[i]=a[i]&ans[tim];      if(t[i].count())      {   if(dfs(tim+1,t))          return 1;      }       t[i]=a[i];//回溯。   }    return 0;}int main(){    int t;   int a;    int cnt;    scanf("%d",&t);    bitset<320>tmp[32];    while(t--)    {   for(int i=0;i<32;i++)          ans[i].reset();        scanf("%d%d",&n,&d);        for(int i=0;i<n;i++)        {  scanf("%d",&cnt);           for(int j=0;j<cnt;j++)           {   scanf("%d",&a);               ans[i][a]=1;           }        }       for(int i=0;i<n;i++)       {   for(int j=0;j<320;j++)           tmp[i][j]=1;//默认状态,全部初始化为1.       }      if(dfs(0,tmp))         printf("YES\n");       else        printf("NO\n");    }}
0 0