题意:n个数组,划分成l个集合,每个集合至少有一个数组,并且一个集合中的数组至少要有一个相同的数,问你是否存在这样的划分方案
思路:L比较小,直接暴力每个数组是在哪个集合里,大约30^5 同时用bitset维护某种集合是否合法,总时间复杂度30^5*300/64 看上去非常的大,其实加上合法性剪纸跑的还是飞快的。。。甚至0ms 。。。黑人问号???
PS.随便搜搜有没有bitset优化的题目,这个题本身不用bitset也完全可以。。因为单个集合元素很少啊。。。300/64感觉未必就比10 能快多少。。。
代码:
#include<bits/stdc++.h>
using namespace std;
#define MEM(a,b) memset(a,b,sizeof(a))
#define bug puts("bug");
#define PB push_back
#define MP make_pair
#define X first
#define Y second
typedef unsigned long long ll;
typedef pair<int,int> pii;
using namespace std;
int n,m,k,x,y,l,t;
bitset<302> B[31];
int dfs(int id,int st,vector<bitset<302> >o,int ans){
if(id==n&&ans==(1<<l)-1) return 1;
if(id==n) return 0;
if((o[st]&=B[id]).count()){
for(int j=0;j<l;j++)
if(dfs(id+1,j,o,ans|(1<<j))) return 1;
}
return 0;
}
int main(){
cin>>t;
while (t--) {
cin>>n>>l;
for(int i=0;i<n;i++){
cin>>x;B[i].reset();
while(x--) cin>>y,B[i].set(y);
}
vector<bitset<302> > O(l);
for(int i=0;i<l;i++) O[i].flip();
for(int i=0;i<l;i++)if(dfs(0,i,O,1<<i)) goto ge;
puts("NO");continue;
ge: puts("YES");
}
return 0;
}