题目链接:http://codeforces.com/contest/986/problem/C
大力dfs,考虑一个点i,则((1<<n)^i)所有包含1的子集,都和i连边,所以,每次暴力dfs某个点的所有子集,大力就能过了...
代码:
#include<bits/stdc++.h> using namespace std; const int MAXN=(1<<22)+5; bool vis[MAXN],has[MAXN],book[MAXN]; int full,n,m; void dfsans(int now); void dfs(int now) { if(vis[now]) return; vis[now]=true; if(has[now]) dfsans(now); for(int i=0;i<n;i++) { if(!(now&(1<<i))) continue; dfs(now^(1<<i)); } } void dfsans(int now) { if(book[now]) return; book[now]=true; dfs(full^now); } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); scanf("%d%d",&n,&m); full=(1<<n)-1; for(int i=1;i<=m;i++) { int x; scanf("%d",&x); has[x]=true; } int ans=0; for(int i=0;i<(1<<n);i++) { if(!has[i]||book[i]) continue; dfsans(i); ans++; } printf("%d\n",ans); return 0; }