Codeforces1009F Dominant Indices

dsu on tree

题目链接

点我跳转

题目大意

给定一棵以 \(1\) 为根,\(n\) 个节点的树。设\(d(u,x)\)\(u\) 子树中到 \(u\) 距离为 \(x\) 的节点数。

对于每个点,求一个最小的 \(k\),使得 \(d(u,k)\) 最大。

解题思路

记录子树每个深度的节点的个数,然后取个最大节点个数的最小深度即可

AC_Code

#include<bits/stdc++.h>
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,n,a) for (int i=n;i>=a;i--)
#define pb push_back
#define fi first
#define se second
using namespace std;
const int N = 1e6 + 10;
struct Edge{
	int nex , to;
}edge[N << 1];
int head[N] , tot;
int a[N] , dep[N] , siz[N] , hson[N] , HH;
int ans[N] , cnt[N] , ma , res;
void add_edge(int u , int v)
{
	edge[++ tot].nex = head[u];
	edge[tot].to = v;
	head[u] = tot;
}
void dfs(int u , int far)
{
	siz[u] = 1;
	dep[u] = dep[far] + 1;
	for(int i = head[u] ; i ; i = edge[i].nex)
	{
		int v = edge[i].to;
		if(v == far) continue ;		
		dfs(v , u);
		siz[u] += siz[v];
		if(siz[v] > siz[hson[u]]) hson[u] = v;
 	}
} 
void calc(int u , int far , int val , int dep)
{
	cnt[dep] += val;
	if(cnt[dep] > ma) ma = cnt[dep] , res = dep;
	else if(cnt[dep] == ma) res = min(res , dep);
	for(int i = head[u] ; i ; i = edge[i].nex)
	{
		int v = edge[i].to;
		if(v == far || v == HH) continue ;
		calc(v , u , val , dep + 1);
	}
}
void dsu(int u , int far, int op , int dep)
{
	for(int i = head[u] ; i ; i = edge[i].nex)
	{
		int v = edge[i].to;
		if(v == far || v == hson[u]) continue ;
		dsu(v , u , 0 , dep + 1);
	}
	if(hson[u]) dsu(hson[u] , u , 1 , dep + 1) , HH = hson[u];
	calc(u , far , 1 , dep);
	HH = 0;
	ans[u] = res - dep;
	if(!op) calc(u , far , -1 , dep) , ma = 0 , res = 0;
}
signed main()
{
	int n , q , tot = 0;
	cin >> n;
	rep(i , 1 , n - 1)
	{
		int u , v;
		cin >> u >> v;
		add_edge(u , v) , add_edge(v , u);	
	} 
	dfs(1 , 0);
	dsu(1 , 0 , 0 , 0);
	rep(i , 1 , n) cout << ans[i] << '\n';
	return 0;
}
posted @ 2020-11-24 02:34  GsjzTle  阅读(186)  评论(0编辑  收藏  举报