题目链接:传送门
很明显的树形,这个点可以被自身,儿子,父亲三个点覆盖
但我们贪心试一下
从最下面的点开始,显然放到最底下一个信号塔是不优的
放到叶子节点的父亲节点会更优,所以每次找到最下面一层节点的上一层节点把它放上信号塔
之后把覆盖的到的节点打上标记,就是已经删除了
然后继续找最下面一层节点的上面一层节点放信号塔,以此类推
正确性没有什么证明,但是确实很有道理
#include <bits/stdc++.h>
#define
using namespace std;
struct node {int next, to;}e[A];
int head[A], num;
void add(int fr, int to) {e[++num].next = head[fr]; e[num].to = to; head[fr] = num;}
int n, fa[A], dep[A], ans, a, b; bool vis[A];
priority_queue<pair<int, int>, vector<pair<int, int>>, less<pair<int, int>> > q;
void dfs(int fr) {
for (int i = head[fr]; i; i = e[i].next) {
int ca = e[i].to;
if (ca == fa[fr]) continue;
fa[ca] = fr; dep[ca] = dep[fr] + 1;
dfs(ca);
}
}
int main(int argc, char const *argv[]) {
cin >> n;
for (int i = 2; i <= n; i++) cin >> a >> b, add(a, b), add(b, a);
fa[1] = 1; dep[1] = 1; dfs(1);
for (int i = 1; i <= n; i++) q.push(make_pair(dep[i], i));
while (!q.empty()) {
int fr = q.top().second; q.pop();
if (vis[fr]) continue;
vis[fa[fr]] = 1; ans++;
for (int i = head[fa[fr]]; i; i = e[i].next) vis[e[i].to] = 1;
}
cout << ans << endl;
return 0;
}