Codeforces1009F Dominant Indices
题目链接
题目大意
给定一棵以 \(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;
}
凡所不能将我击倒的,都将使我更加强大