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] << '
';
	return 0;
}
原文地址:https://www.cnblogs.com/StarRoadTang/p/14028284.html