1. 程式人生 > >CF 551 D.Serval and Rooted Tree 樹形DP

CF 551 D.Serval and Rooted Tree 樹形DP

pro scan first ++ cli == max 樹形 continue

傳送門:http://codeforces.com/contest/1153/problem/D

思路:

這道題想了一天,突發奇想,就是維護每個點兩個值,第幾大和第幾小,就可以有傳遞性了。

技術分享圖片
#include <bits/stdc++.h>

using namespace std;

#define fi first
#define se second
#define pb push_back
typedef long long ll;
typedef pair<int, int> pii;
const ll inff = 0x3f3f3f3f3f3f3f3f
; const int inf = 0x3f3f3f3f; const int maxn = 3e5+9; int a[maxn]; vector<int>mp[maxn]; int dp[maxn][2]; int all = 0; void dfs(int u, int fa) { if(mp[u].size() == 0) dp[u][0] = dp[u][1] = 1, all++; else if(a[u] == 1
) dp[u][0] = 0, dp[u][1] = inf; else if(a[u] == 0) dp[u][0] = inf, dp[u][1] = 0; for(int i=0; i<mp[u].size(); i++) { int v = mp[u][i]; if(v == fa) continue; dfs(v, u); if(a[u] == 1) { dp[u][
1] = min(dp[v][1], dp[u][1]); dp[u][0] += dp[v][0]; } else { dp[u][1] += dp[v][1]; dp[u][0] = min(dp[v][0], dp[v][1]); } } } int main(){ int n; scanf("%d", &n); for(int i=1; i<=n; i++) scanf("%d", &a[i]); for(int i=2; i<=n; i++) { int x; scanf("%d", &x); mp[x].pb(i); } memset(dp, inf, sizeof(dp)); dfs(1, 1); // cout<<" dp[5][1] = " <<dp[5][1]<<endl; // cout<<dp[1][0] << " , " << dp[1][1]<<endl; printf("%d\n", max(dp[1][0], all - dp[1][1] + 1 )); return 0; }
View Code

CF 551 D.Serval and Rooted Tree 樹形DP