题意:有一棵n个节点树,请你构造节点数据使图正好为这棵树(节点之间有边仅这二个节点位与等于图片说明 -1)。

思路:我们可以先黑白染色,因为n<=100,所以一定会有一种颜色少于等于50,所以我们就应该从位上考虑,不然为什么n<=100而不是小于100000呢,又因为只有相邻黑白节点才连接,所以我们可以考虑:将少的染成白色,图片说明 -1用二进制表示为第0-59位都为1.
白色:最高位为0,白色编号的位为0,其余位为1.
黑色:最高位为1,相邻白色的编号的位为1,其余位为0.
这样染色,因为白色最高位为0,所以白色与白色一定不连接。
因为白色个数小于等于50,所以黑色有些位都为0,所以黑色与黑色一定不连接。
相邻的黑白色由于白色为0的位相邻黑色在该位为1,所以相邻黑白色是连接的。
不相邻的黑白色由于白色为0的位不相邻黑色在该位为0(如果为1则说明相邻),所以不相邻黑白色是不连接的。
所以此构造方法正确。

代码:

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

const ll inf=1e9+7;

vector<int> g[1005];

int h=0, b=0, vis[1005], se[1005];
ll jie[1005];

void hbdfs(int v,int f)
{
    if(f==-1)
    {
        vis[v]=0;
    }
    else
    {
        vis[v]=1-vis[f];
    }
    if(vis[v]==1)
    {
        b++;
    }
    else
    {
        h++;
    }
    for(int i=0; i<g[v].size(); i++)
    {
        int u=g[v][i];
        if(vis[u]==-1)
        {
            hbdfs(u,v);
        }
    }
}

int main()
{
    int n;
    scanf("%d",&n);
    memset(vis,-1,sizeof(vis));
    for(int i=1; i<n; i++)
    {
        int u, v;
        scanf("%d%d",&u,&v);
        g[u].push_back(v);
        g[v].push_back(u);
    }
    hbdfs(1,-1);
    int t=0, flag=0;
    if(h<=b)
    {
        flag=0;
    }
    else
    {
        flag=1;
    }
    for(int i=1; i<=n; i++)
    {
        if(vis[i]==flag)
        {
            jie[i]=((1LL<<59)-1)-(1LL<<t);
            se[i]=t;
            t++;
        }
    }
    for(int i=1; i<=n; i++)
    {
        if(vis[i]==1-flag)
        {
            jie[i]=(1LL<<59);
            for(int j=0;j<g[i].size();j++)
            {
                jie[i]=jie[i]+(1LL<<se[g[i][j]]);
            }
        }
    }
    for(int i=1; i<=n; i++)
    {
        printf("%lld%c",jie[i],i==n?'\n':' ');
    }
    return 0;
}