树状贪心
洛谷 P2899 [USACO08JAN]手机网络Cell Phone Network

题目

Farmer John has decided to give each of his cows a cell phone in hopes to encourage their social interaction. This, however, requires him to set up cell phone towers on his N (1 ≤ N ≤ 10,000) pastures (conveniently numbered 1..N) so they can all communicate.

Exactly N-1 pairs of pastures are adjacent, and for any two pastures A and B (1 ≤ A ≤ N; 1 ≤ B ≤ N; A ≠ B) there is a sequence of adjacent pastures such that A is the first pasture in the sequence and B is the last. Farmer John can only place cell phone towers in the pastures, and each tower has enough range to provide service to the pasture it is on and all pastures adjacent to the pasture with the cell tower.

Help him determine the minimum number of towers he must install to provide cell phone service to each pasture.

分析

本题要求使用最少的电磁塔, 把所有的节点覆盖掉. 由 N-1 条边我们可以了解到, 这是一棵树. 从树的叶子节点向上看, 显然在儿子节点摆电磁塔是不合算的. 所以很显然地, 从最后一层向上搜索, 每遇到一个儿子节点没有被覆盖, 就在他父亲上摆一个电磁塔. 很显然, 从下向上枚举, 对于本题的数据这种方法是成立的.

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#pragma GCC optimize ("Ofast")

#include "iostream"
#include "stdio.h"
#include "vector"

#define rint register int

using namespace std;

inline int read()
{
int x=0ll,t=1ll;
char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}

bool check[10001];
int n, fa[10001], ans, mxdp;
vector <int> mp[10001], fl[10001];

inline void dfs (int u, int de)
{
mxdp = max (mxdp, de);
fl[de].push_back (u);
int v;
for (rint i = 0; i < mp[u].size (); ++ i)
{
v = mp[u][i];
if (!(v ^ fa[u])) continue;
fa[v] = u;
dfs (v, de + 1);
}
}

inline void work (int u)
{
check[u] = true;
for (rint i = 0; i < mp[u].size (); ++ i) check[mp[u][i]] = true;
}

signed main ()
{
n = read ();
int u, v;
for (rint i = 1; i < n; ++ i)
{
u = read (), v = read ();
mp[u].push_back (v);
mp[v].push_back (u);
}

dfs (1, 0);

for (rint i = mxdp; i >= 0; -- i)
{
for (rint j = 0; j < fl[i].size (); ++ j)
{
u = fl[i][j], v = fa[u];
if (check[u]) continue;
ans ++;
work (v);
}
}
printf ("%d", ans);
}

Comments

Please contact the Administrator directly for emergency.





GitHub release (latest by date including pre-releases) GitHub release (latest by date including pre-releases) GitHub repo size GitHub repo size PictureBed PictureBed

Blog content follows the Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) License

Copyright 2017-2020 ELLIAS views, viewersLoading... Loading...
MOE ICP 辽ICP备20009666号-1 | MOE ICP MOEICP备20201096号