​传送门​

我们按照深度的奇偶性染色,那么其实树是一张二分图

边的两端一定是一黑一白

由于同组内部无边,不同组可能有边

那么让白点末两位为01,黑点末两位为10,这样同组内不可能会有边

然后来处理黑白点间的关系

我们把第一个白点前58位赋值为11…110

第二个白点前58位赋值为11…101

第三个百点前58位赋值为11…011

以此类推,那么第 i i i个白点需要的 1 1 1在第 59 − i 59-i 59−i位上

也就是每个白点需要的二进制位各不相同

那么与之相邻的黑点只在这些位补 1 1 1

所以每个黑点除了和自己相邻的白点连边,不可能会向其他白点连边了,因为没有它需要的二进制位

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 309;
const int base = (1ll<<58)-1;
int id,n,f[maxn],deep[maxn],color[3],white;
struct edge{
int to,nxt;
}d[maxn]; int head[maxn],cnt=1;
void add(int u,int v){ d[++cnt] = (edge){v,head[u]},head[u] = cnt; }
void dfs(int u,int fa,int depth)
{
deep[u] = depth; color[deep[u]%2]++;
for(int i=head[u];i;i=d[i].nxt )
{
int v = d[i].to;
if( v==fa ) continue;
dfs(v,u,depth+1);
}
}
void perfect(int u,int fa)
{
if( deep[u]%2==white ){ f[u] = base^(1ll<<id); id++; }//白点
for(int i=head[u];i;i=d[i].nxt )
{
int v = d[i].to;
if( v==fa ) continue;
if( deep[u]%2==white ) f[v] |= (base^f[u] );//白点给儿子黑点
perfect(v,u);
if( deep[u]%2!=white ) f[u] |= (base^f[v] );//白点给父亲黑点
}
}
signed main()
{
cin >> n;
for(int i=1;i<n;i++)
{
int l,r; cin >> l >> r;
add(l,r); add(r,l);
}
dfs(1,0,0);
if( color[0]<color[1] ) white = 0;
else white = 1;
perfect(1,0);
for(int i=1;i<=n;i++)
{
if( deep[i]%2==white ) f[i] += (1ll<<58);
else f[i] += (1ll<<59);
cout << f[i] << " ";
}
}