GYM102769K Kingdoms' Power(樹形DP+回溯)
阿新 • • 發佈:2020-10-28
題意:
有一棵根節點為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(); } }