CF1009F Dominant Indices
给定一棵以 1 为根,n 个节点的树。设 d(u,x) 为 u 子树中到 u 距离为 x 的节点数。
对于每个点,求一个最小的 k,使得 d(u,k) 最大。
#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
using namespace std;
const int M = 2100001;
int n,m,k,a[M],ver[M],nex[M],head[M],cnt;
int tmp[M], *id=tmp, *f[M],ans[M];
int dp[M],h[M],md[M];
void add(int x,int y)
{
ver[++cnt]=y, nex[cnt]=head[x], head[x]=cnt;
ver[++cnt]=x, nex[cnt]=head[y], head[y]=cnt;
}
void dfs_(int x,int fa)
{
dp[x]=md[x]=dp[fa]+1;
for(int i=head[x];i;i=nex[i])
{
if(ver[i]==fa) continue;
dfs_(ver[i],x);
md[x]=max(md[x],md[ver[i]]);
if(md[ver[i]]>md[h[x]]) h[x]=ver[i];
}
}
void dfs(int x,int fa)
{
if(h[x]) f[h[x]]=f[x]+1, dfs(h[x],x), ans[x]=ans[h[x]]+1;
f[x][0]=1;
for(int i=head[x];i;i=nex[i])
{
if(ver[i]==fa || ver[i]==h[x]) continue;
f[ver[i]]=id; id+=md[ver[i]]-dp[ver[i]]+1; dfs(ver[i],x);
for(int j=0;j<=md[ver[i]]-dp[ver[i]];j++)
{
f[x][j+1]+=f[ver[i]][j];
if(f[x][j+1]>f[x][ans[x]] || (f[x][j+1]==f[x][ans[x]] && j+1<ans[x])) ans[x]=j+1;
}
}
if(f[x][ans[x]]<=1) ans[x]=0;
}
int main()
{
scanf("%d",&n);
int x,y;
for(int i=1;i<n;i++) scanf("%d%d",&x,&y), add(x,y);
dfs_(1,0);
f[1]=id; id+=md[1]; dfs(1,0);
for(int i=1;i<=n;i++) printf("%d\n",ans[i]);
}