题解 CF1009F 【Dominant Indices】
FutaRimeWoawaSete · · 题解
以为十二篇题解里面怎么也得有启发式合并老哥,没想到真的没有。
按理来说这道题不是归于启发式合并的经典例题里面吗?
首先启发式合并有点小卡,如果您追求于更快的做法不妨使用树上倍增。
其次就讲解一些此题如何树上启发式合并,很明显这道题符合我们树上启发式合并的一些基本特征,即:
1.只具备查询操作;
2.只和子树有关;
所以考虑到了
时间复杂度
唯一注意的就是要考虑怎么初始化
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
const int Len = 1e6 + 5;
int Mx,Dis,n,m,Cnt[Len],head[Len],cnt,Print[Len],dep[Len],siz[Len],son[Len],Son;
struct node
{
int next,to;
}edge[Len << 1];
void add(int from,int to)
{
edge[++ cnt].to = to;
edge[cnt].next = head[from];
head[from] = cnt;
}
void dfs1(int x,int f)
{
dep[x] = dep[f] + 1;
siz[x] = 1;
int maxson = -1;
for(int e = head[x] ; e ; e = edge[e].next)
{
int to = edge[e].to;
if(to == f) continue;
dfs1(to , x);
siz[x] += siz[to];
if(siz[to] > maxson) maxson = siz[to] , son[x] = to;
}
}
void add(int x,int f,int val,int now)
{
Cnt[dep[x]] += val;
if(Cnt[dep[x]] > Mx || (Cnt[dep[x]] == Mx && dep[x] - dep[now] < Dis - dep[now])) Mx = Cnt[dep[x]] , Dis = dep[x];
for(int e = head[x] ; e ; e = edge[e].next)
{
int to = edge[e].to;
if(to == f || to == Son) continue;
add(to , x , val , now);
}
}
void dfs2(int x,int f,int opt)
{
for(int e = head[x] ; e ; e = edge[e].next)
{
int to = edge[e].to;
if(to == f || to == son[x]) continue;
dfs2(to , x , 0);
}
if(son[x]) dfs2(son[x] , x , 1) , Son = son[x];
add(x , f , 1 , x) , Son = 0;
Print[x] = Dis;
if(!opt) add(x , f , -1 , x) , Mx = Dis = 0;
}
int main()
{
scanf("%d",&n);
for(int i = 1 ; i < n ; i ++)
{
int x,y;scanf("%d %d",&x,&y);
add(x , y) , add(y , x);
}
dfs1(1 , 0);
dfs2(1 , 0 , 1);
for(int i = 1 ; i <= n ; i ++) printf("%d\n",Print[i] - dep[i]);
return 0;
}