zoukankan      html  css  js  c++  java
  • uva1267 Network

    https://vjudge.net/problem/UVA-1267

    题意:

    有一棵树,上面有一个放着水源的点s,给出一个数k,这个水源可以覆盖路径长度到s不超过k的叶子节点。现在需要把所有的叶子节点都用水源覆盖,问至少需要再放置多少个水源。

    思路:

    首先,这种树的问题并且明显提供了一个特殊点的题,我们可以把无根树转化为有根树简化需要解决的问题。

    这题,经过转化之后,所有的深度小于等于k的节点,我们都不考虑了,只考虑深度大于k的叶子节点。

    在无根树转化为有根树的过程中,把所有的深度大于k的叶子节点用一个深度对应的数组存起来。

    之后,我们从最深的深度开始枚举,这个深度的如果有叶子节点并且没有被覆盖的话,那么我们就找到这个节点的第k级父亲(直接父亲是第一级),从这个祖先节点开始一次dfs,标记深度不超过k的所有节点。

    解释:

    从最深的深度开始枚举,并且找到它的第k级父亲这个操作,可以保证我们加的水源是最少的,假设k为4,如果用它的第3级父亲开始dfs,那么如果第4级父亲还有其它叶子节点,就没有被覆盖,但是我们在第四级父亲,既可以把这个深度的所有节点都覆盖,并且可以把第四级父亲之下的所有的叶子节点都覆盖,那么说明父亲的级别越高,那么可能覆盖的点就会越多,那么当前的点的第k级父亲就是可以覆盖到这个点的级别最高的父亲。

    注意:

    在dfs中,建图是建的双向图,所以一定要判断下一个dfs的点是不是与父亲节点相等。Debug了很久。。。

    代码:

      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <vector>
      4 using namespace std;
      5 
      6 vector<int> g[1005],node[1005];
      7 int n,s,k;
      8 bool cover[10005];
      9 int fa[1005];
     10 
     11 void dfs(int pre,int cur,int dep)
     12 {
     13     //printf("*
    ");
     14 
     15     fa[cur] = pre;
     16 
     17     if (g[cur].size() == 1 && dep > k) node[dep].push_back(cur);
     18 
     19     for (int i = 0;i < g[cur].size();i++)
     20     {
     21         int to = g[cur][i];
     22 
     23         if (to != pre) dfs(cur,to,dep + 1);
     24     }
     25 }
     26 
     27 void dfs2(int v,int d)
     28 {
     29     //printf("**
    ");
     30 
     31     cover[v] = 1;
     32 
     33     for (int i = 0;i < g[v].size();i++)
     34     {
     35         int to = g[v][i];
     36 
     37         if (to != v && d < k) dfs2(to,d+1);
     38     }
     39 }
     40 
     41 int solve(void)
     42 {
     43     memset(cover,0,sizeof(cover));
     44 
     45     int ans = 0;
     46 
     47     for (int d = n - 1;d > k;d--)
     48     {
     49         for (int i = 0;i < node[d].size();i++)
     50         {
     51             int x = node[d][i];
     52 
     53             //printf("%d ** 
    ",x);
     54 
     55             if (cover[x]) continue;
     56 
     57             //printf("0000
    ");
     58 
     59             for (int j = 0;j < k;j++) x = fa[x];
     60 
     61             dfs2(x,0);
     62 
     63             ans++;
     64         }
     65     }
     66 
     67     return ans;
     68 }
     69 
     70 int main()
     71 {
     72     int t;
     73 
     74     scanf("%d",&t);
     75 
     76     while (t--)
     77     {
     78         scanf("%d",&n);
     79 
     80         scanf("%d%d",&s,&k);
     81 
     82         for (int i = 0;i <= n;i++) 
     83         {
     84             node[i].clear();
     85             g[i].clear();
     86         }
     87 
     88         for (int i = 0;i < n - 1;i++)
     89         {
     90             int x,y;
     91 
     92             scanf("%d%d",&x,&y);
     93 
     94             g[x].push_back(y);
     95             g[y].push_back(x);
     96         }
     97 
     98         dfs(-1,s,0);
     99 
    100         printf("%d
    ",solve());
    101     }
    102 
    103     return 0;
    104 }
  • 相关阅读:
    ASP.NET + EF + SQL Server搭建个人博客系统新手系列(一):界面展示
    PHP中文乱码分类及解决办法大全
    分享一个根据具体的日期判断星座的PHP函数
    WHERE条件中or与union引起的全表扫描的问题
    linux下SVN CVS命令大全
    Ubuntu装完后要做的几件事
    Table被web编程弃用的原因
    PHP json_decode返回null解析失败原因
    powerpoint教程资料,PPT的
    一些matlab教程资源收藏,使用matlab编程的人还是挺多的
  • 原文地址:https://www.cnblogs.com/kickit/p/7615706.html
Copyright © 2011-2022 走看看