zoukankan      html  css  js  c++  java
  • 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
    ", solve());
    83     }
    84     return 0;
    85 }
    代码君
  • 相关阅读:
    List
    美团Leaf分布式ID生成策略
    单点登陆
    ElasticSearch
    Eureka
    Nginx
    UML
    Computer English
    加密
    Excel中把一列数据转换成逗号隔开的一行
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/3923891.html
Copyright © 2011-2022 走看看