Luogu 2279 [HNOI2003]消防局的设立 - 贪心
Description
给定一棵树形图, 建若干个消防站, 消防站能够覆盖到距离不超过2的点, 求最少需要建几个消防站才能覆盖所有点
Solution
从深度最深的点开始, 在它的爷爷节点上建, 每建一次都要把能覆盖的点都记录下来。
执行的次数就是答案。
Code
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define rd read() 5 using namespace std; 6 7 const int N = 1e3 + 5; 8 9 int n, f[N], id[N], vis[N], dep[N]; 10 int ans, head[N], tot; 11 12 struct edge { 13 int nxt, to; 14 }e[N]; 15 16 int read() { 17 int X = 0, p = 1; char c = getchar(); 18 for(; c > '9' || c < '0'; c = getchar()) if(c == '-') p = -1; 19 for(; c >= '0' && c <= '9'; c = getchar()) X = X * 10 + c - '0'; 20 return X * p; 21 } 22 23 void add(int u, int v) { 24 e[++tot].to = v; 25 e[tot].nxt = head[u]; 26 head[u] = tot; 27 } 28 29 int cmp(int a, int b) { 30 return dep[a] > dep[b]; 31 } 32 33 void dfs(int x) { 34 if(!x) return; 35 vis[x] = 1; 36 for(int i = head[x]; i; i = e[i].nxt) { 37 int nt = e[i].to; 38 vis[nt] = 1; 39 } 40 } 41 42 void col(int x) { 43 vis[x] = 1; vis[f[x]] = 1; 44 dfs(f[x]); dfs(f[f[x]]); 45 x = f[f[x]]; 46 vis[x] = 1; vis[f[x]] = 1; 47 dfs(f[x]); 48 vis[f[f[x]]] = 1; 49 for(int i = head[x]; i; i = e[i].nxt) dfs(e[i].to); 50 } 51 52 int main() 53 { 54 n = rd; 55 dep[1] = 1; 56 for(int i = 2; i <= n; ++i) { 57 f[i] = rd; 58 dep[i] = dep[f[i]] + 1; 59 add(f[i], i); 60 } 61 for(int i = 1; i <= n; ++i) id[i] = i; 62 sort(id + 1, id + n + 1, cmp); 63 for(int i = 1; i <= n; ++i) { 64 if(vis[id[i]]) continue; 65 ans++; 66 col(id[i]); 67 } 68 printf("%d\n", ans); 69 }