• Codeforces 987 F


    F - AND Graph

    思路:

    首先,x & (~x) == 0

    其次,~x 的 子集 y = ((~x) ^ (1<<k)), 0<= k < n(如果k这一位是1),y&x == 0 

    所以枚举 a[i] ,如果a[i]每被标记,搜索 (~a[i])的子集, 子集的子集......,边搜索边标记元素,如果出现一个y也属于a[i],那么再搜索(~y)的子集

    这样就能保证一个联通图里的元素都能在一次搜索里被标记完

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define fi first
    #define se second
    #define pi acos(-1.0)
    #define LL long long
    #define mp make_pair
    #define pb push_back
    #define ls rt<<1, l, m
    #define rs rt<<1|1, m+1, r
    #define ULL unsigned LL
    #define pll pair<LL, LL>
    #define pii pair<int, int>
    #define mem(a, b) memset(a, b, sizeof(a))
    #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
    //head
    
    const int N = 8e6 + 5;
    int a[N], tot, n;
    bool hs[N], vis[N];
    void dfs(int x) {
        if(vis[x]) return ;
        vis[x] = true;
        if(hs[x]) dfs(tot ^ x);
        for (int i = 0; i < n; i++) {
            if(x & (1<<i)) dfs(x ^ (1<<i));
        }
    }
    int main() {
        int m;
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= m; i++) scanf("%d", &a[i]), hs[a[i]] = true;
        tot = (1<<n) - 1;
        int ans = 0;
        for (int i = 1; i <= m; i++) {
            if(!vis[a[i]]) {
                ans++;
                vis[a[i]] = true;
                dfs(tot ^ a[i]);
            }
        }
        printf("%d
    ", ans);
        return 0;
    }
  • 相关阅读:
    Servlet学习之http
    初识JDBC-篇四
    初识JDBC-篇三
    正则表达式简单应用3
    正则表达式简单应用2
    正则表达式简单应用1
    反射的简单应用三
    反射的简单应用2
    反射简单的应用
    TCP协议应用--上传文件
  • 原文地址:https://www.cnblogs.com/widsom/p/9121860.html
Copyright © 2020-2023  润新知