CF1009F Dominant Indices(启发式合并)

You are given a rooted undirected tree consisting of nn vertices. Vertex 11 is the root.

Let's denote a depth array of vertex xx as an infinite sequence [dx,0,dx,1,dx,2,][dx,0,dx,1,dx,2,…], where dx,idx,i is the number of vertices yy such that both conditions hold:

  • xx is an ancestor of yy;
  • the simple path from xx to yy traverses exactly ii edges.

The dominant index of a depth array of vertex xx (or, shortly, the dominant index of vertex xx) is an index jj such that:

  • for every k<jk<j, dx,k<dx,jdx,k<dx,j;
  • for every k>jk>j, dx,kdx,jdx,k≤dx,j.

For every vertex in the tree calculate its dominant index.

Input

The first line contains one integer nn (1n1061≤n≤106) — the number of vertices in a tree.

Then n1n−1 lines follow, each containing two integers xx and yy (1x,yn1≤x,y≤n, xyx≠y). This line denotes an edge of the tree.

It is guaranteed that these edges form a tree.

Output

Output nn numbers. ii-th number should be equal to the dominant index of vertex ii.

Examples

Input
4
1 2
2 3
3 4
Output
0
0
0
0
Input
4
1 2
1 3
1 4
Output
1
0
0
0
Input
4
1 2
2 3
2 4
Output
2
1
0
0
题解:题目意思为:给你一颗有根数,对于每一个节点,他的子树到他的边数为d,到达他的边数为d的数量为fd,让你求每一个节点fd最大的d,如果有多个选择d最小的那个;
用map<int,int> mp[i][d]:表示节点I的子树中的节点中深度为d(表示到根节点的边数)的数量。然后沿着重边一直往下搜索,启发式搜索,每次更新ans[u]即可;
参考代码:
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define clr(a,val) memset(a,val,sizeof(a))
 4 #define pb push_back
 5 #define fi first
 6 #define se second
 7 typedef long long ll;
 8 const int maxn=1e6+10;
 9 inline int read()
10 {
11     int x=0,f=1;char ch=getchar();
12     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
13     while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
14     return x*f;
15 }
16 struct Edge{
17     int to,nxt;
18 } edge[maxn<<1];
19 int n,cnt,dep[maxn],hvy[maxn],hson[maxn],head[maxn<<1];
20 int maxd[maxn],ans[maxn];
21 map<int,int> mp[maxn];
22 inline void addedge(int u,int v)
23 {
24     edge[cnt].to=v;
25     edge[cnt].nxt=head[u];
26     head[u]=cnt++;
27 }
28 inline void dfs1(int u,int fa)
29 {
30     hvy[u]=dep[u];
31     for(int e=head[u];~e;e=edge[e].nxt)
32     {
33         int v=edge[e].to;
34         if(v==fa) continue;
35         dep[v]=dep[u]+1;
36         dfs1(v,u);
37         if(hvy[v]>hvy[u])
38         {
39             hson[u]=v;
40             hvy[u]=hvy[v];//子树的最深深度 
41         }
42     }
43 }
44 inline void dfs2(int u,int fa)
45 {
46     for(int e=head[u];~e;e=edge[e].nxt)
47     {
48         int v=edge[e].to;
49         if(v==fa) continue;
50         dfs2(v,u);
51     }
52     if(hson[u]>0)
53     {
54         int v=hson[u];
55         swap(mp[u],mp[v]);
56         mp[u][dep[u]]=1;
57         if(maxd[v]>1)
58         {
59             maxd[u]=maxd[v];
60             ans[u]=ans[v]+1;
61         }
62         else maxd[u]=1,ans[u]=0;
63     }
64     else maxd[u]=1,ans[u]=0,mp[u][dep[u]]=1;
65     map<int,int>::iterator it;
66     for(int i=head[u];~i;i=edge[i].nxt)
67     {
68         int v=edge[i].to;
69         if(v==fa || v==hson[u]) continue;
70         for(it=mp[v].begin();it!=mp[v].end();it++)
71         {
72             mp[u][(*it).fi]+=mp[v][(*it).fi];
73             if(mp[u][(*it).fi]>maxd[u])
74             {
75                 maxd[u]=mp[u][(*it).fi];
76                 ans[u]=(*it).fi-dep[u];
77             }
78             if(mp[u][(*it).fi]==maxd[u] && (*it).fi-dep[u]<ans[u]) ans[u]=(*it).fi-dep[u];
79         }
80     }
81 }
82 
83 
84 int main()
85 {
86     n=read();int u,v;
87     cnt=0;clr(head,-1);
88     for(int i=0;i<=n;++i) mp[i].clear();
89     for(int i=1;i<n;++i)
90     {
91         u=read(),v=read(); 
92         addedge(u,v);addedge(v,u);    
93     } 
94     dep[1]=1;dfs1(1,0);dfs2(1,0);
95     for(int i=1;i<=n;++i) printf("%d%c",ans[i],i==n? '\n':' ');
96     return 0;
97 }
View Code

猜你喜欢

转载自www.cnblogs.com/songorz/p/10293337.html
今日推荐