返回首页 C++ 模板

树形DP之最小点覆盖模板

选最少的点覆盖所有边

最小点覆盖 树形DP GESP6
#include <bits/stdc++.h>
using namespace std;

const int N = 10010;
vector<int> adj[N];
// dp[u][0] = 不选u的最小覆盖, dp[u][1] = 选u的最小覆盖
int dp[N][2];

void dfs(int u, int fa) {
    dp[u][0] = 0;
    dp[u][1] = 1;  // 选u则覆盖数+1
    for (int v : adj[u]) {
        if (v == fa) continue;
        dfs(v, u);
        dp[u][0] += dp[v][1];                  // 不选u,子节点必须选(覆盖u-v边)
        dp[u][1] += min(dp[v][0], dp[v][1]);    // 选u,子节点可选可不选
    }
}

int main() {
    int n;
    cin >> n;
    for (int i = 1; i < n; i++) {
        int u, v; cin >> u >> v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    dfs(1, 0);
    cout << min(dp[1][0], dp[1][1]) << endl;
    return 0;
}

📖 要点说明

⚠️ 常见错误