AND Graph CodeForces - 987F(思维二进制dfs)

题意:给出n
(0n22)和m,和m个数ai≤ ≤ 20ai<2,把a& a== 0 的连边,求最后有几个连通块

解析:一个一个去找肯定爆,那么就要转换一下思维,想一下什么样的数才能按位与ai为0

那么肯定是a^ ((1<<n)-1)的子集,所以去找它的所有子集即可

例1010  变成0101  子集有 0101  0100  0001

然后只有x是给出的那m个数种的时候 才能 ^ ,其他情况消1取子集

#include <bits/stdc++.h>
#define mem(a, b) memset(a, b, sizeof(a))
using namespace std;
const int maxn = (1<<22) + 5, INF = 0x7fffffff;
int n, m, res;
int a[maxn], vis[maxn], inc[maxn];

void dfs(int x)
{
    if(vis[x]) return;
    vis[x] = 1;
    if(inc[x])
    {
        dfs(x^((1<<n)-1));
    }
    for(int i=0; i<n; i++)
    {
        if(x&(1<<i))
        {
            int temp = x^(1<<i);
            if(!vis[temp])
            {
                dfs(temp);
            }
        }
    }
}

int main()
{
    mem(vis, 0);
    mem(inc, 0);
    scanf("%d%d", &n, &m);
    res = 0;
    for(int i=0; i<m; i++)
    {
        scanf("%d", &a[i]);
        inc[a[i]] = 1;
    }
    for(int i=0; i<m; i++)
        if(!vis[a[i]])
        {
            vis[a[i]] = 1;
            res++;
            dfs(a[i]^((1<<n)-1));
        }

    cout<< res <<endl;


    return 0;
}

 

 

 

posted @ 2018-08-23 21:28  WTSRUVF  阅读(365)  评论(0编辑  收藏  举报