题目链接:http://codeforces.com/problemset/problem/321/C
题意:给出一棵树,为每个节点分配一个大写字母A到Z。满足对于任意两个字母相同的节点u和v,uv的路径上至少存在一个节点的字母是大于uv的字母的(A最大)。
思路:每次找到当前树的重心,将其分成若干个子树继续进行DFS。总深度大于26则无解。否则每个树的字母为其深度。
vector<int> g[N],V1,V2;
int size[N],visit[N];
int n;
void DFS(int u,int pre)
{
size[u]=1;
int i,v,son=0;
FOR0(i,SZ(g[u]))
{
v=g[u][i];
if(visit[v]||v==pre) continue;
DFS(v,u);
size[u]+=size[v];
if(size[v]>son) son=size[v];
}
V1.pb(son); V2.pb(u);
}
int getRoot(int u)
{
V1.clear(); V2.clear();
DFS(u,-1);
int tot=SZ(V1);
int i,Min=INF,temp,ans;
FOR0(i,SZ(V1))
{
temp=max(V1[i],tot-V1[i]);
if(temp<Min) Min=temp,ans=V2[i];
}
return ans;
}
int dep[N],MaxDep;
void solve(int u,int d)
{
u=getRoot(u); MaxDep=max(MaxDep,d);
dep[u]=d;
visit[u]=1;
int i,v;
FOR0(i,SZ(g[u]))
{
v=g[u][i];
if(visit[v]) continue;
solve(v,d+1);
}
}
int main()
{
RD(n);
int i,x,y;
FOR1(i,n-1)
{
RD(x,y);
g[x].pb(y);
g[y].pb(x);
}
solve(1,0);
if(MaxDep>=26)
{
puts("Impossible!");
return 0;
}
printf("%c",dep[1]+'A');
for(i=2;i<=n;i++) printf(" %c",dep[i]+'A');
puts("");
return 0;
}