旅游(树形dp,树上最大独立集)
旅游
https://ac.nowcoder.com/acm/problem/15748
题目:
给一个树形城市网络。一开始住在s城,第一天游览距离s城≤1的城市,然后住进另一个未游览的城市,第二天重复游览步骤。问最多能游览多少天。
做法:
题意转化一下,让你选尽量多的城市,使城市之间两两不相邻。这就是树上的最大独立集问题。
树形dp,dp[u][0/1]表示点u选/不选时,子树u下的最大独立集的点的数量。 u选了,儿子v就不能选。
u不选时,儿子v可选可不选。
城市网络以s为根,答案是dp[s][1]
代码:
#include <bits/stdc++.h>
#define debug(a) cout << #a ": " << a << endl
#define IOS ios::sync_with_stdio(false), cin.tie(0)
using namespace std;
typedef long long ll;
const int N = 5e5 + 7;
int n, s, dp[N][2];
vector<int> g[N];
void dfs(int u, int p){
dp[u][0] = 1;
for (int i = 0; i < g[u].size(); ++i){
int v = g[u][i];
if (v == p) continue;
dfs(v, u);
dp[u][0] += dp[v][1];
dp[u][1] += max(dp[v][0], dp[v][1]);
}
}
int main(void){
IOS;
cin >> n >> s;
for (int i = 0; i < n-1; ++i){
int u, v; cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
dfs(s, s);
cout << dp[s][0] << endl;
return 0;
}

