chenfy27的刷题记录

导航

luoguP2016 战略游戏

给定一棵n个结点的树,至少要选多少个点才能覆盖所有边?边的两个端点至少有一个被选中则认为覆盖。
1<=n<=1500

分析:设dp[i][0]表示以i为根的子树,不选i的答案,同理dp[i][1]为选i的答案。自下而上dp,如果选了i,那么其子节点可以选或不选;如果不选i,那么其子节点必须选。

#include <bits/stdc++.h>
using i64 = long long;

void solve() {
	int n;
	std::cin >> n;
	std::vector<std::vector<int>> adj(n);
	for (int i = 0; i < n; i++) {
		int x, y;
		std::cin >> x >> y;
		for (int j = 0; j < y; j++) {
			int z;
			std::cin >> z;
			adj[x].push_back(z);
			adj[z].push_back(x);
		}
	}

	std::vector<std::array<int,2>> dp(n);

	auto dfs = [&](auto self, int x, int p) -> void {
		dp[x][0] = 0;
		dp[x][1] = 1;
		for (auto i : adj[x]) if (i != p) {
			self(self, i, x);
			dp[x][0] += dp[i][1];
			dp[x][1] += std::min(dp[i][0], dp[i][1]);
		}
	};

	dfs(dfs, 0, 0);

	std::cout << std::min(dp[0][0], dp[0][1]) << "\n";
}

int main() {
	std::cin.tie(0)->sync_with_stdio(0);
	int t = 1;
	while (t--) solve();
	return 0;
}

posted on 2024-11-03 15:33  chenfy27  阅读(2)  评论(0编辑  收藏  举报