[关闭]
@Chilling 2017-01-21T10:21:22.000000Z 字数 2547 阅读 1275

CodeForces-321C: Ciel the Commander(点分治)

树分治


Description

Now Fox Ciel becomes a commander of Tree Land. Tree Land, like its name said, has n cities connected by n - 1 undirected roads, and for any two cities there always exists a path between them.

Fox Ciel needs to assign an officer to each city. Each officer has a rank — a letter from 'A' to 'Z'. So there will be 26 different ranks, and 'A' is the topmost, so 'Z' is the bottommost.

There are enough officers of each rank. But there is a special rule must obey: if x and y are two distinct cities and their officers have the same rank, then on the simple path between x and y there must be a city z that has an officer with higher rank. The rule guarantee that a communications between same rank officers will be monitored by higher rank officer.

Help Ciel to make a valid plan, and if it's impossible, output "Impossible!".

Input

The first line contains an integer n — the number of cities in Tree Land.

Each of the following n - 1 lines contains two integers a and b — they mean that there will be an undirected road between a and b. Consider all the cities are numbered from 1 to n.

It guaranteed that the given graph will be a tree.

Output

If there is a valid plane, output n space-separated characters in a line — i-th character is the rank of officer in the city with number i.

Otherwise output "Impossible!".

Example

Input

4
1 2
1 3
1 4

Output

A B B B

Input

10
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10

Output

D C B A D C B D C D

Note

In the first example, for any two officers of rank 'B', an officer with rank 'A' will be on the path between them. So it is a valid solution.

题意:给出一棵树,给每一个点填上一个字母(A到Z,A最大)。要求每两个等级相同的点之间一定存在另一个点的等级更高。

分析:每次找出树的重心,从A到Z赋值,找出赋值之后将它删去,接着找它剩下的子树的各个重心。A到Z一共26个字母,但是已经大于了100000,这就说明我们一定能用字母表示所有点的等级,而不会输出Impossible。(SPJ)


  1. #include<stdio.h>
  2. #include<algorithm>
  3. #include<vector>
  4. #include<string.h>
  5. using namespace std;
  6. vector<int>v[100005];
  7. int ans[100005],vis[100005];
  8. int sz[100005];
  9. int rt;
  10. void getsz(int u,int fa) //得到size,即包含该节点在内以及它下方的节点个数
  11. {
  12. sz[u]=1;
  13. for(int i=0;i<v[u].size();i++)
  14. {
  15. int next=v[u][i];
  16. if(next==fa||vis[next]) continue;
  17. getsz(next,u);
  18. sz[u]+=sz[next];
  19. }
  20. }
  21. void getrt(int u,int fa,int totsz)
  22. {
  23. int upsz=totsz-sz[u];//u节点上方的大小
  24. int dnsz=-1;//下方的大小
  25. if(upsz>totsz/2) return;
  26. for(int i=0;i<v[u].size();i++)
  27. {
  28. int next=v[u][i];
  29. if(next==fa||vis[next]) continue;
  30. dnsz=max(dnsz,sz[next]);
  31. getrt(next,u,totsz);
  32. }
  33. if(max(upsz,dnsz)<=totsz/2)
  34. rt=u;
  35. }
  36. void getans(int id,int dep)
  37. {
  38. getsz(id,0);
  39. getrt(id,0,sz[id]);//以当前的节点id为起点,父节点为0
  40. int rtt=rt;
  41. vis[rtt]=1;
  42. ans[rtt]=dep+1;
  43. for(int i=0;i<v[rtt].size();i++)
  44. {
  45. int next=v[rtt][i];
  46. if(vis[next]) continue;
  47. getans(next,dep+1);
  48. }
  49. }
  50. int main()
  51. {
  52. int n,a,b;
  53. while(scanf("%d",&n)!=EOF)
  54. {
  55. memset(vis,0,sizeof(vis));
  56. for(int i=1;i<n;i++)
  57. {
  58. scanf("%d%d",&a,&b);
  59. v[a].push_back(b);
  60. v[b].push_back(a);
  61. }
  62. getans(1,0);
  63. for(int i=1;i<=n;i++)
  64. printf("%c ",ans[i]+'A');
  65. printf("\n");
  66. for(int i=0;i<=n;i++)
  67. v[i].clear();
  68. }
  69. return 0;
  70. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注