Educational Codeforces Round 47 (Rated for Div. 2) -F Dominant Indices

版权声明:欢迎转载蒟蒻博客,但请注明出处: https://blog.csdn.net/LPA20020220/article/details/86490855

洛谷传送门

Codeforces传送门

题意翻译

给出一棵有根树,对于每个节点 x x ,定义一个无穷序列 d d ,其中 d ( x , i ) d(x,i) 表示以 x x 为根节点的子树中到 x x 的距离恰好为 i i 的点的个数, i = 0 i=0\sim \infin ,现在对每个点 x x ,希望求出一个值 j j ,使得对于任意 k < j k<j d ( x , k ) < d ( x , j ) d(x,k)<d(x,j) ,对于任意 k > j , d ( x , k ) d ( x , j ) k>j,d(x,k)\le d(x,j)

输入输出格式

输入格式:

第一行一个整数 n n ,表示树的节点个数 接下来 n 1 n-1 行,每行两个整数, x x y y ,表示 x , y x,y 之间有一条连边

输出格式:

n n 行,每行一个整数,第 i i 行表示 x = i x=i 时对应的 j j

输入输出样例

输入样例#1:

4
1 2
2 3
3 4

输出样例#1:

0
0
0
0

输入样例#2:

4
1 2
1 3
1 4

输出样例#2:

1
0
0
0

输入样例#3:

4
1 2
2 3
2 4

输出样例#3:

2
1
0
0

解题分析

长链剖分模板题。没什么好说的…

注意转移重儿子的时候写假了还能过138个点…

代码如下:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <cstdlib>
#include <algorithm>
#define R register
#define IN inline
#define W while
#define gc getchar()
#define MX 1005000
template <class T>
IN void in(T &x)
{
    x = 0; R char c = gc;
    for (; !isdigit(c); c = gc);
    for (;  isdigit(c); c = gc)
    x = (x << 1) + (x << 3) + c - 48;
}
int n, cnt;
struct Edge {int to, nex;} edge[MX << 1];
int buf[MX << 2], *dp[MX], *pt = buf;
int dep[MX], head[MX], son[MX], ans[MX];
IN void add(R int from, R int to)
{edge[++cnt] = {to, head[from]}, head[from] = cnt;}
void DFS(R int now, R int fa)
{
    for (R int i = head[now]; i; i = edge[i].nex)
    {
        if (edge[i].to == fa) continue;
        DFS(edge[i].to, now);
        if (dep[edge[i].to] > dep[son[now]]) son[now] = edge[i].to;
    }
    dep[now] = dep[son[now]] + 1;
}
IN void nw(R int now) {dp[now] = pt; pt += dep[now] + 2;}
void DP(R int now, R int fa)
{
    int mx = 0;
    dp[now][0] = 1;
    if (!son[now]) return;
    dp[son[now]] = dp[now] + 1;
    DP(son[now], now); ans[now] = ans[son[now]] + 1; mx = dp[now][ans[now]];
    for (R int i = head[now]; i; i = edge[i].nex)
    {
        if (edge[i].to == fa || edge[i].to == son[now]) continue;
        nw(edge[i].to);
        DP(edge[i].to, now);
        for (R int j = 0; j < dep[edge[i].to]; ++j)
        {
            dp[now][j + 1] += dp[edge[i].to][j];
            if (dp[now][j + 1] > mx) ans[now] = j + 1, mx = dp[now][j + 1];
            else if (dp[now][j + 1] == mx && ans[now] > j + 1) ans[now] = j + 1;
        }
    }
    if (dp[now][ans[now]] == 1) ans[now] = 0;
}
int main(void)
{
    in(n); int foo, bar;
    for (R int i = 1; i < n; ++i)
    in(foo), in(bar), add(foo, bar), add(bar, foo);
    DFS(1, 0); nw(1);
    DP(1, 0);
    for (R int i = 1; i <= n; ++i) printf("%d\n", ans[i]);
}

猜你喜欢

转载自blog.csdn.net/LPA20020220/article/details/86490855