Codeforces Round #485 (Div. 1) C. AND Graph(dfs)

题目链接: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;
}


猜你喜欢

转载自blog.csdn.net/sinat_32872703/article/details/80515292