Codeforces 442D Adam and Tree dp (看题解)

Adam and Tree

感觉非常巧妙的一题。。

如果对于一个已经建立完成的树, 那么我们可以用dp[ i ]表示染完 i 这棵子树, 并给从fa[ i ] -> i的条边也染色的最少颜色数。

mnson[ i ][ 0 ] 和 mnson[ i ][ 1 ]分别表示 i 的儿子的dp值的最大和第二大的值, 那么dp[ i ] = max(mnson[ i ][ 0 ], mnson[ i ][ 1 ] + 1)

根据树链剖分的原理我们知道dp的最大值不超过log(n), 那么每次加入一个新的点, 我们暴力地往上更新dp值, 直到当前的dp值不变。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ull unsigned long long

using namespace std;

const int N = 1e6 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1000000007;
const double eps = 1e-6;
const double PI = acos(-1);

int n, fa[N], mxson[N][2], dp[N];

int main() {
    scanf("%d", &n);
    for(int i = 2; i <= n + 1; i++) scanf("%d", &fa[i]);
    for(int i = 2; i <= n + 1; i++) {
        int u = i;
        while(1) {
            if(u == 1 || dp[u] >= max(mxson[u][0], mxson[u][1] + 1)) break;
            dp[u] = max(mxson[u][0], mxson[u][1] + 1);
            if(dp[u] >= mxson[fa[u]][0]) {
                mxson[fa[u]][1] = mxson[fa[u]][0];
                mxson[fa[u]][0] = dp[u];
            } else if(dp[u] > mxson[fa[u]][1]) {
                mxson[fa[u]][1] = dp[u];
            }
            u = fa[u];
        }
        printf("%d ", mxson[1][0]);
    }
    puts("");
    return 0;
}

/*
*/

 

posted @ 2019-03-26 13:04  NotNight  阅读(226)  评论(0编辑  收藏  举报