【每日一题】40. 旅游 (树形DP解决树的最大独立集)
补题链接:Here
算法涉及:树形DP寻找树上最大独立集
一开始想到是利用 树形DP 找树的直径问题,但这里由于可以利用走过的点衍生,所以不符合树的直径问题
查询了一下资料这道题是属于:
树的最大独立集,就是这样的一个集合,这些集合里面的点在树中互不相邻。
树形dp可以解决这个问题,\(dp[u][0]\) 表示不在 \(u\) 的最大独立集, \(dp[u][1]\) 表示在最大独立集里
显然有递推方程
- \(dp[u][1] += dp[v][1]\)
- \(dp[u][0] = max(dp[v][0],dp[v][1])\)
不要忘记 \(dp[u][1] = 1\) , 自己也在最大独立集里。
最后输出 \(dp[s][1]\)
const int N = 5e5 + 10;
vector<int>e[N];
int dp[N][2];
void dfs(int u, int fa) {
dp[u][0] = dp[u][1] = 0;
for (int v : e[u]) {
if (v == fa)continue;
dfs(v, u);
dp[u][1] += dp[v][0];
dp[u][0] += max(dp[v][1], dp[v][0]);
}
dp[u][1]++; // 自己也在最大独立集里
}
void solve() {
int n, s;
cin >> n >> s;
for (int i = 1; i <= n - 1; ++i) {
int u, v; cin >> u >> v;
e[u].push_back(v);
e[v].push_back(u);
}
dfs(s, -1);
cout << dp[s][1];
}