启发式合并CodeForces - 1009F
Posted jkzr
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了启发式合并CodeForces - 1009F相关的知识,希望对你有一定的参考价值。
E - Dominant Indices CodeForces - 1009F
You are given a rooted undirected tree consisting of nn vertices. Vertex 11 is the root.
Let‘s denote a depth array of vertex xx as an infinite sequence [dx,0,dx,1,dx,2,…][dx,0,dx,1,dx,2,…], where dx,idx,i is the number of vertices yy such that both conditions hold:
- xx is an ancestor of yy;
- the simple path from xx to yy traverses exactly ii edges.
The dominant index of a depth array of vertex xx (or, shortly, the dominant index of vertex xx) is an index jj such that:
- for every k<jk<j, dx,k<dx,jdx,k<dx,j;
- for every k>jk>j, dx,k≤dx,jdx,k≤dx,j.
For every vertex in the tree calculate its dominant index.
Input
The first line contains one integer nn (1≤n≤1061≤n≤106) — the number of vertices in a tree.
Then n?1n?1 lines follow, each containing two integers xx and yy (1≤x,y≤n1≤x,y≤n, x≠yx≠y). This line denotes an edge of the tree.
It is guaranteed that these edges form a tree.
Output
Output nn numbers. ii-th number should be equal to the dominant index of vertex ii.
Examples
4
1 2
2 3
3 4
0
0
0
0
4
1 2
1 3
1 4
1
0
0
0
4
1 2
2 3
2 4
2
1
0
0
题意:对于每一个节点x,可以定义一个深度数组[dx0,dx1,dx2,…dxh],代表着以节点x为根往下计算,深度为h的那层的节点的数量。
对于每一个节点x,我们可以从深度数组中,选择一个主要索引下标j,作为他的代表。这个dj需要满足以下条件,他是所有dh中,最大的那个,如果有多个dh是一样的,都是最大的,那么选择j(即深度)最小的那个。
每层节点数的众数。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long LL;
const int maxn=1e6+5;
int n,m;
int mx,big,id;
int deep[maxn],si[maxn],hson[maxn],cnt[maxn],ans[maxn];
vector<int>G[maxn];
void findhson(int x,int fa,int dep)//找到所有的重儿子
{
si[x]=1;
deep[x]=dep;
int len=G[x].size();
for(int i=0;i<len;i++)
{
int t=G[x][i];
if(t!=fa)
{
findhson(t,x,dep+1);
si[x]+=si[t];
deep[t]=deep[x]+1;
if(si[t]>si[hson[x]])
hson[x]=t;
}
}
}
void cal(int x,int fa,int val)
{
cnt[deep[x]]+=val;
if(cnt[deep[x]]>mx)
{
id=deep[x];
mx=cnt[deep[x]];
}
else if(cnt[deep[x]]==mx && deep[x]<id)
id=deep[x];
int len=G[x].size();
for(int i=0;i<len;i++)
{
int t=G[x][i];
if(t!=fa && t!=big)
cal(t,x,val);
}
}
void dfs(int x,int fa,int flag)
{
int len=G[x].size();
for(int i=0;i<len;i++)
{
int t=G[x][i];
if(t!=fa && t!=hson[x])
dfs(t,x,0);
}
if(hson[x])
{
dfs(hson[x],x,1);
big=hson[x];
}
cal(x,fa,1);
big=0;
ans[x]=id;
if(!flag)
{
cal(x,fa,-1);
mx=0;id=0;
}
}
int main()
{
big=0;mx=0;id=0;
scanf("%d",&n);
int x,y;
for(int i=1;i<n;i++)
{
scanf("%d %d",&x,&y);
G[x].push_back(y);
G[y].push_back(x);
}
findhson(1,0,1);
dfs(1,0,1);
for(int i=1;i<=n;i++)
printf("%d
",ans[i]-deep[i]);
return 0;
}
以上是关于启发式合并CodeForces - 1009F的主要内容,如果未能解决你的问题,请参考以下文章
CodeForces - 778C: Peterson Polyglot (启发式合并trie树)
CodeForces 600E. Lomsat gelral树上启发式合并
CodeForces 375D. Tree and Queries树上启发式合并
CodeForces 958F3 Lightsabers (hard) 启发式合并/分治 多项式 FFT