LA 3902 Network

人生第一道图论题啊,有木有

题意:

有一个树状网络,有一个原始服务器s,它的服务范围是k

问至少再放多少台服务范围是k的服务器才能使网络中的每个节点都被覆盖掉

解法:

我们以原始服务器为根将其转化成一个有根树,则深度不超过k的节点都已经被原始服务器覆盖。

我们选择深度最大的节点u然后将它的k级祖先设为服务器,进行一次DFS,将所有距离它不超过k的节点覆盖。

表示:

图的表示在这里面是用邻接表来表示的,如果a、b两个节点相邻,则gr[a]中放入b,gr[b]中放入a

怎样才算转化为有根树了?那就是把每个节点的爸爸(father)算出来,记录在fa数组中

试想,如果深度大于k的节点都已被覆盖,那么其他非叶子节点也一顶被覆盖了

所以将深度大于k的节点放在nodes表中

 

 1 //#define LOCAL
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <vector>
 5 #include <algorithm>
 6 using namespace std;
 7 
 8 const int maxn = 1000 + 10;
 9 vector<int> gr[maxn], nodes[maxn];
10 int n, s, k, fa[maxn];
11 bool coverd[maxn];
12 
13 void DFS(int u, int f, int d)
14 {//计算各个节点的祖先,放在fa数组中
15     fa[u] = f;
16     int nc = gr[u].size();
17     if(nc == 1 && d > k)
18         nodes[d].push_back(u);
19     for(int i = 0; i < nc; ++i)
20     {
21         int v = gr[u][i];
22         if(v != f)
23             DFS(v, u, d + 1);
24     }
25 }
26 
27 void DFS2(int u, int f, int d)
28 {
29     coverd[u] = true;
30     int nc = gr[u].size();
31     for(int i = 0; i < nc; ++i)
32     {
33         int v = gr[u][i];
34         if(v != f && d < k)
35             DFS2(v, u, d + 1);
36     }
37 }
38 
39 int solve(void)
40 {
41     int ans = 0;
42     memset(coverd, false, sizeof(coverd));
43     for(int d = n - 1; d > k; --d)
44         for(int i = 0; i < nodes[d].size(); ++i)
45         {
46             int u = nodes[d][i];
47             if(coverd[u])    continue;
48 
49             int v = u;
50             for(int i = 0; i < k; ++i)    //v是u的k级祖先
51                 v = fa[v];
52             DFS2(v, -1, 0);
53             ++ans;
54         }
55     return ans;
56 }
57 
58 int main(void)
59 {
60     #ifdef LOCAL
61         freopen("3902in.txt", "r", stdin);
62     #endif
63 
64     int T;
65     scanf("%d", &T);
66     while(T--)
67     {
68         scanf("%d%d%d", &n, &s, &k);
69         for(int i = 1; i <= n; ++i)
70         {
71             gr[i].clear();
72             nodes[i].clear();
73         }
74         for(int i = 0; i < n - 1; ++i)
75         {
76             int a, b;
77             scanf("%d%d", &a, &b);
78             gr[a].push_back(b);
79             gr[b].push_back(a);
80         }
81         DFS(s, -1, 0);
82         printf("%d\n", solve());
83     }
84     return 0;
85 }
代码君

 

posted @ 2014-08-20 10:00  AOQNRMGYXLMV  阅读(230)  评论(0编辑  收藏  举报