Cell Phone Networ (树形dp-最小支配集)

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.

Input

  • Line 1: A single integer: N
  • Lines 2..N: Each line specifies a pair of adjacent pastures with two space-separated integers: A and B

Output

  • Line 1: A single integer indicating the minimum number of towers to install

Sample Input

5

1 3

5 2

4 3

3 5

Sample Output

2

题意

任意一点都要有信号塔或者在信号塔周围(信号塔范围为 1 )。那么至少要有多少信号塔。

思路

首先确定几种状态

  • dp[x][0] :不放塔但是在范围内
  • dp[x][1] :不放塔且不在范围内
  • dp[x][2] :放塔

由于是由子节点推父节点,故下面在计算某点状态的时候,只考虑其子节点的状态。因为,只需计算出当前节点自己的所有状态,而用哪种状态是父节点的事。

  1. 对于不放塔但是在范围内的,肯定是某个子节点有塔。

    但是所有子节点为了最优,都没有选择塔,那怎么办。

    这时候就需要,选择一个变成有塔的差值最小的一个子节点。所以在遍历子节点时,就要记录下放塔与不放塔最小差值,和changed标记。如果需要,就加上差值。
  2. 对于不放塔但是不在范围内的,只要其继续错下去就好了。但是,这是只考虑子节点的情况。在父节点放塔的时候,这个点可能又变成在信号内了,所以这种状态要保证其所有子节点都是合理的。这样父节点只要考虑这个节点就好,不需要关心下面的节点了。

    这样得dp[now][1]+=dp[son][0] 为什么是dp[son][0],因为子节点合理并且子节点没有信号塔啊。
  3. 对于放塔的,子节点怎么放都行,所以得dp[u][2] += min(dp[v][0], min(dp[v][1], dp[v][2]))
  4. 当然别忘了初始化每个节点。

题解

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <vector>
  5. #include <algorithm>
  6. #define N 100005
  7. #define INF 0x3f3f3f
  8. using namespace std;
  9. vector<int> eg[N];
  10. int dp[N][3], foo[N], vis[N];
  11. int n, x, y;
  12. void dfs(int u)
  13. {
  14. dp[u][0] = dp[u][1] = 0;
  15. dp[u][2] = 1;
  16. vis[u] = 1;
  17. int minmall = INF, f = 0;
  18. for (int i = 0; i < eg[u].size(); i++)
  19. {
  20. int v = eg[u][i];
  21. if (vis[v])
  22. continue;
  23. dfs(v);
  24. minmall = (minmall, dp[v][2] - dp[v][0]);
  25. //记录差值
  26. if (dp[v][2] <= dp[v][0])
  27. f = 1;
  28. //子节点能放就放,应为还能照顾父节点。所以这里是 <=
  29. //如果子节点有放塔的,就标记,差值就无需在加了。
  30. dp[u][0] += min(dp[v][2], dp[v][0]);
  31. dp[u][1] += dp[v][0];
  32. dp[u][2] += min(dp[v][0], min(dp[v][1], dp[v][2]));
  33. }
  34. if (f == 0)//如果没有子节点放塔,加上使差值最小的节点放上塔。
  35. dp[u][0] += minmall;
  36. }
  37. int main()
  38. {
  39. while (cin >> n)
  40. {
  41. memset(dp, 0, sizeof dp);
  42. memset(vis, 0, sizeof vis);
  43. memset(foo, -1, sizeof foo);
  44. for (int i = 0; i < n - 1; i++)
  45. {
  46. cin >> x >> y;
  47. eg[x].push_back(y);
  48. eg[y].push_back(x);
  49. foo[y] = x;
  50. }
  51. int root = 1;
  52. while (foo[root] != -1)
  53. root = foo[root];
  54. vis[root] = 1;
  55. dfs(root);
  56. cout << min(dp[root][0], dp[root][2]) << endl;
  57. for (int i = 1; i <= n; i++)
  58. eg[i].clear();
  59. }
  60. }

Cell Phone Networ (树形dp-最小支配集)的更多相关文章

  1. POJ3659 Cell Phone Network(树上最小支配集:树型DP)

    题目求一棵树的最小支配数. 支配集,即把图的点分成两个集合,所有非支配集内的点都和支配集内的某一点相邻. 听说即使是二分图,最小支配集的求解也是还没多项式算法的.而树上求最小支配集树型DP就OK了. ...

  2. 树形DP 树的最小支配集,最小点覆盖与最大独立集

    最小支配集: 从V中选取尽量少的点组成一个集合,让V中剩余的点都与取出来的点有边相连. (点) 最小点覆盖: 从V中选取尽量少的点组成一个集合V1,让所有边(u,v)中要么u属于V1,要么v属于V1 ...

  3. 求树的最大独立集,最小点覆盖,最小支配集 贪心and树形dp

    目录 求树的最大独立集,最小点覆盖,最小支配集 三个定义 贪心解法 树形DP解法 (有任何问题欢迎留言或私聊&&欢迎交流讨论哦 求树的最大独立集,最小点覆盖,最小支配集 三个定义 最大 ...

  4. 树形DP求树的最小支配集,最小点覆盖,最大独立集

    一:最小支配集 考虑最小支配集,每个点有两种状态,即属于支配集合或者不属于支配集合,其中不属于支配集合时此点还需要被覆盖,被覆盖也有两种状态,即被子节点覆盖或者被父节点覆盖.总结起来就是三种状态,现对 ...

  5. 树形dp(最小支配集)

    http://poj.org/problem?id=3659 #include<iostream> #include<cstring> #include<algorith ...

  6. POJ 3659 Cell Phone Network / HUST 1036 Cell Phone Network(最小支配集,树型动态规划,贪心)-动态规划做法

    POJ 3659 Cell Phone Network / HUST 1036 Cell Phone Network(最小支配集,树型动态规划,贪心) Description Farmer John ...

  7. POJ 3659 Cell Phone Network(树的最小支配集)(贪心)

    Cell Phone Network Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6781   Accepted: 242 ...

  8. poj-3659 Cell Phone Network(最小支配集+贪心)

    http://poj.org/problem?id=3659 Description Farmer John has decided to give each of his cows a cell p ...

  9. POJ 3398 Perfect Service --最小支配集

    题目链接:http://poj.org/problem?id=3398 这题可以用两种上述讲的两种算法解:http://www.cnblogs.com/whatbeg/p/3776612.html 第 ...

随机推荐

  1. Codeforces Round #564 (Div. 2)A

    A. Nauuo and Votes 题目链接:http://codeforces.com/contest/1173/problem/A 题目 Nauuo is a girl who loves wr ...

  2. Oracle 数据库表中已有重复数据添加唯一键(唯一约束)

    Oracle 数据库表中已有重复数据添加唯一键(唯一约束) 问题描述 以 demo 举例,模拟真实场景. 表 TEST_TABLE 有如下字段和数据:id 是主键,code 没有设置键和索引 ID C ...

  3. java中方法的重载和覆盖

    java中方法的重载和覆盖 先来了解一下这两个名词的含义. 重载: 在一个类当中才可以重载,方法名相同,参数个数不同或参数个数相同而参数类型不同. 覆盖: 又称重写,在派生类(子类)中重写基类(父类) ...

  4. Rxjs中Notification 介绍

    timer(0, 1000) // 计时器,每1000ms发射一个值,初始发射值延迟时间为0s: .pipe( take(5), // 取前5个值 takeWhile(value => valu ...

  5. POI 身份证号码 手机号 日期值的处理方式

    private static SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); ...

  6. Adobe全系软件下载安装工具 CCMaker 1.3.6

    CCMaker是俄罗斯大神El Sanchez开发的一款集Adobe软件全家桶下载.安装.激活一条龙服务的小工具. 程序小巧强大,使用微软通用运行库开发,效率高体积小. 注意,此程序需要安装微软通用C ...

  7. springmvc上传文件踩过的坑

    @RequestMapping("/addTweet") public String addTweet(TweetVO tweetVO, HttpServletRequest re ...

  8. PostgreSQL 窗口函数 ( Window Functions ) 如何使用?

    一.为什么要有窗口函数 我们直接用例子来说明,这里有一张学生考试成绩表testScore: 现在有个需求,需要查询的时候多出一列subject_avg_score,为此科目所有人的平均成绩,好跟每个人 ...

  9. Bzoj 2563: 阿狸和桃子的游戏 题解

    2563: 阿狸和桃子的游戏 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 970  Solved: 695[Submit][Status][Discu ...

  10. AT173 単位:题解

    题目链接:https://www.luogu.org/problemnew/show/AT173 分析: 首先,我们可以做如下排序: sort(a+1,a+1+n); 因为题目告诉我们了要出席最少的次 ...