AT3912 Antennas on Tree
https://www.luogu.com.cn/problem/AT3912
想了一会,大概想到了
考虑选择的的那\(k\)个点连起来,一定是一棵树,考虑把这棵树挖掉,剩下的点度数一定都\(\le 2\)(原树上),否则一定会存在一对兄弟节点的坐标是相同的
那么解法也很简单了,只需要对于每个度数为\(1\)的点,暴力往上跳,找到第一个度数\(\ge 2\)的,打个标记,容易发现在一个标记下支配的叶子结点最多只能剩下一个不选,那么用叶子结点数减去标记点数即可
code:
#include<bits/stdc++.h>
#define N 200050
using namespace std;
int in[N], n, vis[N];
vector<int> g[N];
int dfs(int u, int fa) {
if(in[u] > 2) return u;
for(int v : g[u])
if(v != fa) return dfs(v, u);
return u;
}
int main() {
scanf("%d", &n);
for(int i = 1; i < n; i ++) {
int u, v;
scanf("%d%d", &u, &v); u ++, v ++;
g[u].push_back(v), g[v].push_back(u);
in[u] ++, in[v] ++;
}
int ans = 0;
for(int i = 1; i <= n; i ++) if(in[i] == 1) vis[dfs(i, 0)] = 1, ans ++;
//for(int i = 1; i <= n; i ++) printf("%d ", vis[i]); printf("\n");
for(int i = 1; i <= n; i ++) ans -= vis[i];
if(!ans) ans = 1;
printf("%d", ans);
return 0;
}