AFO

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]); 
}
posted @ 2020-01-14 20:42  ZUTTER☮  阅读(146)  评论(0编辑  收藏  举报