https://codeforces.com/problemset/problem/1009/F
You are given a rooted undirected tree consisting of n vertices. Vertex 1 is the root.
Let’s denote a depth array of vertex x as an infinite sequence [dx,0,dx,1,dx,2,…], where dx,i is the number of vertices y such that both conditions hold:
x is an ancestor of y;
the simple path from x to y traverses exactly i edges.
The dominant index of a depth array of vertex x (or, shortly, the dominant index of vertex x) is an index j such that:
for every k<j, dx,k<dx,j;
for every k>j, dx,k≤dx,j.
For every vertex in the tree calculate its dominant index.
Input
The first line contains one integer n (1≤n≤106) — the number of vertices in a tree.
Then n−1 lines follow, each containing two integers x and y (1≤x,y≤n, x≠y). This line denotes an edge of the tree.
It is guaranteed that these edges form a tree.
Output
Output n numbers. i-th number should be equal to the dominant index of vertex i.
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
题目大意:题目描述比较抽象,其实就是求一棵树中以每个节点作为根节点的子树时,该子树哪一层的节点数目最多,如果有多层节点数目都相等的话,取最浅的那一层。
思路:dsu on tree模板题,相关介绍请戳。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+5;
struct Edge
{
int to,nxt;
}edge[maxn<<1];
int head[maxn],siz[maxn],son[maxn],deep[maxn],cnt[maxn],ans[maxn];
int n,tot,Son,MAX,idx;
inline void addedge(int u,int v)
{
edge[++tot].to=v,edge[tot].nxt=head[u],head[u]=tot;
}
void dfs1(int u,int f,int dep)
{
int v;
siz[u]=1,deep[u]=dep;
for(int i=head[u];i;i=edge[i].nxt)
{
v=edge[i].to;
if(v==f)
continue;
dfs1(v,u,dep+1);
siz[u]+=siz[v];
if(siz[v]>siz[son[u]])
son[u]=v;
}
}
void modify(int u,int f,int val)
{
cnt[deep[u]]+=val;
if(cnt[deep[u]]>MAX)
MAX=cnt[deep[u]],idx=deep[u];
else if(cnt[deep[u]]==MAX)
idx=min(idx,deep[u]);
int v;
for(int i=head[u];i;i=edge[i].nxt)
{
v=edge[i].to;
if(v==f||v==Son)
continue;
modify(v,u,val);
}
}
void dfs2(int u,int f,bool tag)
{
int v;
for(int i=head[u];i;i=edge[i].nxt)
{
v=edge[i].to;
if(v==f||v==son[u])
continue;
dfs2(v,u,0); //轻儿子
}
if(son[u])
dfs2(son[u],u,1),Son=son[u];//重儿子
modify(u,f,1);//递归计算子树贡献
ans[u]=idx;//记录答案
Son=0;
if(!tag)//清除轻儿子贡献
{
modify(u,f,-1);
idx=MAX=0;
}
}
int main()
{
scanf("%d",&n);
int u,v;
for(int i=1;i<n;i++)
{
scanf("%d %d",&u,&v);
addedge(u,v),addedge(v,u);
}
dfs1(1,0,0);
dfs2(1,0,0);
for(int i=1;i<=n;i++)
printf("%d\n",ans[i]-deep[i]);
return 0;
}