zoukankan      html  css  js  c++  java
  • [ICPC2020济南J] Tree Constructer

    [ICPC2020济南J] Tree Constructer - 构造

    Description

    给定一棵树,让你给节点赋值,要求相连的两个点的值进行或操作后结果为 (2^{60}-1)

    Solution

    我们要将所有点分成两部分,使得边都在两部分之间,我们可以通过双标志位来使得两个部分内部互相不连边

    现在只要搞定两部分之间的连边就可以了

    我们对较少的那部分,每个点分配一个独立的编号 (1,2,3,4,...),除了标志位(放在高位)外,其余的都打成 (1),只有编号对应的位打成 (0),类似 (0111 1110, 0111 1101, ...) 这样

    对于较多的那部分,尽可能让更多的位是 (0),而它相邻的少点,对应编号位设为 (1),这样就能保证,只与相邻的少点连边(因为少点空成 (0) 的地方它都填 (1) 了),而不与其它少点相连

    考虑怎么写得简单一点,我们开一堆长度为 60 的 bitset,最后转成 ulong 即可

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    
    const int N = 205;
    
    int n, c[N];
    bitset<60> a[N];
    vector<int> g[N];
    
    void dfs(int p, int from)
    {
        for (int q : g[p])
        {
            if (q != from)
            {
                c[q] = 1 - c[p];
                dfs(q, p);
            }
        }
    }
    
    signed main()
    {
        ios::sync_with_stdio(false);
        cin >> n;
        for (int i = 1; i < n; i++)
        {
            int t1, t2;
            cin >> t1 >> t2;
            g[t1].push_back(t2);
            g[t2].push_back(t1);
        }
        dfs(1, 0);
    
        int cnt[2] = {0, 0};
        for (int i = 1; i <= n; i++)
            cnt[c[i]]++;
        if (cnt[0] > cnt[1])
        {
            for (int i = 1; i <= n; i++)
                c[i] = 1 - c[i];
        }
        int ind = 0;
        map<int, int> mp;
        for (int i = 1; i <= n; i++)
            if (c[i] == 0)
            {
                a[i][59] = 0;
                a[i][58] = 1;
                for (int j = 57; j >= 0; j--)
                    a[i][j] = 1;
                a[i][ind++] = 0;
                mp[i] = ind - 1;
            }
        for (int i = 1; i <= n; i++)
            if (c[i] == 1)
            {
                a[i][59] = 1;
                a[i][58] = 0;
                for (int j = 57; j >= 0; j--)
                    a[i][j] = 0;
                for (auto q : g[i])
                    a[i][mp[q]] = 1;
            }
        for (int i = 1; i <= n; i++)
        {
            int tmp = 0;
            for (int j = 0; j < 60; j++)
                if (a[i][j])
                    tmp |= 1ll << j;
            cout << tmp << " ";
        }
    }
    
    
  • 相关阅读:
    MySQL常用函数及逻辑运算
    博客主题2
    TCPIP详解第1卷1.3TCPIP分层1.4互联网的地址1.5域名系统1.6封装
    删除数组中满足特定需求的数字
    自定义简洁浏览器主页
    Matlab图像处理函数:regionprops
    连通域的质心
    Matlab的GUI参数传递方式总结
    retrifit
    association ,collection
  • 原文地址:https://www.cnblogs.com/mollnn/p/14563246.html
Copyright © 2011-2022 走看看