[CF1029E] Tree with Small Distances - 贪心,树形dp
Description
给定一颗有根树(根节点为 (1))。要求往树中加入一些边使得从根节点到其他节点的距离至多是 (2)。 求加入边的最小数量。
Solution
贪心,每次将叶子的父亲向根连边,不断重复即可
暴力做挺麻烦,考虑对点染色(然后变成了一个类似树形 dp 的东西)
叶子染色为 2,其余点为所有孩子的最小值 +1 后对 3 取模
这样染出来,0 表示这个点有往根的连边,1 表示这个点的某个孩子有往根的连边,2 表示这个点的父亲有往根的连边
根和根的孩子是不需要考虑的,统计答案的时候忽略掉即可
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 5;
int n, f[N], fa[N];
vector<int> g[N];
void dfs(int p, int from = 0)
{
f[p] = 2;
for (int q : g[p])
{
if (q == from)
continue;
fa[q] = p;
dfs(q, p);
f[p] = min(f[p], (f[q] + 1) % 3);
}
}
signed main()
{
ios::sync_with_stdio(false);
cin >> n;
for (int i = 1; i < n; i++)
{
int u, v;
cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
dfs(1);
int ans = 0;
for (int i = 2; i <= n; i++)
if (f[i] == 0 && fa[i] != 1)
++ans;
cout << ans << endl;
}