首页 > 其他 > 详细

GYM102769K Kingdoms' Power(树形DP+回溯)

时间:2020-10-28 14:17:53      阅读:38      评论:0      收藏:0      [点我收藏+]

题意:

有一棵根节点为1的树,根节点处有无限个部队,每次操作你能让一个部队移动一步,问你最少移动多少次可以遍历完这个树。

题解:

非常巧妙的树形DP,跪了

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+100;
int n;
vector<int> g[maxn];
int pre[maxn];
int dep[maxn];
int maxDep[maxn];
long long ans;
void dfs1 (int u,int f) {
    dep[u]=dep[f]+1;
    maxDep[u]=dep[u];
    for (int v:g[u]) {
        if (v!=f) {
            dfs1(v,u);
            maxDep[u]=max(maxDep[u],maxDep[v]);
            //更新距离它最远的叶子节点是多少 
        }
    }
} 

long long dfs2 (int u,int f) {
    pre[u]=u;
    for (int v:g[u]) {
        if (v==f) continue;
        ans+=min(dep[u],dep[pre[u]]-dep[u]+1);
        dfs2(v,u);
        pre[u]=pre[v];
    }
}
bool cmp (int x,int y) {
    return maxDep[x]<maxDep[y];
}
int main () {
    int T;
    scanf("%d",&T);
    for (int k=1;k<=T;k++) {
        int n;
        scanf("%d",&n);
        ans=0;
        for (int i=2;i<=n;i++) {
            int x;
            scanf("%d",&x);
            g[x].push_back(i);
            g[i].push_back(x);
        }
        dfs1(1,0);
        for (int i=1;i<=n;i++) sort(g[i].begin(),g[i].end(),cmp);
        dfs2(1,0);
        printf("Case #%d: %lld\n",k,ans);
        for (int i=1;i<=n;i++) g[i].clear();
    }
}

 

GYM102769K Kingdoms' Power(树形DP+回溯)

原文:https://www.cnblogs.com/zhanglichen/p/13890346.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!