感觉这种类型的dp以前没遇到过。。。 不是很好想。。
dp[u] 表示的是以u为子树进行游戏得到的值是第几大的。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PII pair<int, int> #define y1 skldjfskldjg #define y2 skldfjsklejg using namespace std; const int N = 2e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; int n, sum[N], dp[N], f[N], dp2[N]; vector<int> edge[N]; void dfs(int u, int fa) { for(int v : edge[u]) { if(v == fa) continue; f[u] = true; dfs(v, u); sum[u] += sum[v]; } sum[u] += !f[u]; } void dfs2(int u, int fa, int depth) { if(!f[u]) { dp[u] = 1; dp2[u] = 1; return; } if(depth & 1) { dp2[u] = inf; for(int v : edge[u]) { if(v == fa) continue; dfs2(v, u, depth + 1); dp[u] += dp[v]; dp2[u] = min(dp2[u], dp2[v]); } } else { dp[u] = inf; for(int v : edge[u]) { if(v == fa) continue; dfs2(v, u, depth + 1); dp[u] = min(dp[u], dp[v]); dp2[u] += dp2[v]; } } } int main() { scanf("%d", &n); for(int i = 1; i < n; i++) { int u, v; scanf("%d%d", &u, &v); edge[u].push_back(v); edge[v].push_back(u); } dfs(1, 0); dfs2(1, 0, 0); printf("%d %d\n", sum[1] - dp[1] + 1, dp2[1]); return 0; } /* 5 1 5 4 3 2 */
原文地址:https://www.cnblogs.com/CJLHY/p/9671050.html
时间: 2024-10-08 04:34:26