PT07X - Vertex Cover

简单 DP。

考虑 fi,0f_{i,0}fi,1f_{i,1} 分别表示 ii 点不选和选的情况下以 ii 为根的子树的最小点覆盖。

对于叶子节点 uufu,0=0f_{u,0}=0fu,1=1f_{u,1}=1

对于非叶子节点,fu,0=jsonufj,1f_{u,0} = \sum \limits_{j \in son_u} f_{j,1}fu,1=1+jsonumin{fj,0,fj,1}f_{u,1} = 1 + \sum \limits_{j \in son_u} \min\{f_{j,0},f_{j,1}\}

即如果这个点不选,这个点的每个儿子必须选,否则不满足每条边至少有一个节点被选。

如果选了这个点,儿子可以选也可以不选,不影响结果。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
using namespace std;

const int N = 1e5 + 5;

int f[N][2];
int n;
vector<int> G[N];

void dfs(int u, int fa)
{
	f[u][0] = 0;
	f[u][1] = 1;
	int c = 0;
	for (int j : G[u])
	{
		if (j != fa)
		{
			dfs(j, u);
			c++;
		}
	}
	if (!c) return;
	for (int j : G[u])
	{
		if (j != fa)
		{
			f[u][0] += f[j][1];
			f[u][1] += min(f[j][0], f[j][1]);
		}
	}
}

int main()
{
	scanf("%d", &n);
	for (int i = 1; i < n; i++)
	{
		int u, v;
		scanf("%d%d", &u, &v);
		G[u].emplace_back(v);
		G[v].emplace_back(u);
	}
	dfs(1, 0);
	printf("%d\n", min(f[1][0], f[1][1]));
	return 0;
}
posted @   HappyBobb  阅读(7)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示