博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Cell Phone Networ (树形dp-最小支配集)
阅读量:4873 次
发布时间:2019-06-11

本文共 2869 字,大约阅读时间需要 9 分钟。

目录

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. 当然别忘了初始化每个节点。

题解

#include 
#include
#include
#include
#include
#define N 100005#define INF 0x3f3f3fusing namespace std;vector
eg[N];int dp[N][3], foo[N], vis[N];int n, x, y;void dfs(int u){ dp[u][0] = dp[u][1] = 0; dp[u][2] = 1; vis[u] = 1; int minmall = INF, f = 0; for (int i = 0; i < eg[u].size(); i++) { int v = eg[u][i]; if (vis[v]) continue; dfs(v); minmall = (minmall, dp[v][2] - dp[v][0]); //记录差值 if (dp[v][2] <= dp[v][0]) f = 1; //子节点能放就放,应为还能照顾父节点。所以这里是 <= //如果子节点有放塔的,就标记,差值就无需在加了。 dp[u][0] += min(dp[v][2], dp[v][0]); dp[u][1] += dp[v][0]; dp[u][2] += min(dp[v][0], min(dp[v][1], dp[v][2])); } if (f == 0)//如果没有子节点放塔,加上使差值最小的节点放上塔。 dp[u][0] += minmall;}int main(){ while (cin >> n) { memset(dp, 0, sizeof dp); memset(vis, 0, sizeof vis); memset(foo, -1, sizeof foo); for (int i = 0; i < n - 1; i++) { cin >> x >> y; eg[x].push_back(y); eg[y].push_back(x); foo[y] = x; } int root = 1; while (foo[root] != -1) root = foo[root]; vis[root] = 1; dfs(root); cout << min(dp[root][0], dp[root][2]) << endl; for (int i = 1; i <= n; i++) eg[i].clear(); }}

转载于:https://www.cnblogs.com/tttfu/p/11293850.html

你可能感兴趣的文章
unity, copy-paste component
查看>>
nginx常见面试题1
查看>>
小白用shiro(1)
查看>>
微服务化之无状态化与容器化
查看>>
动态规划LeetCode174地下城游戏
查看>>
(十二)文件处理基础
查看>>
ubuntu 下更改分辨率
查看>>
Java 并发专题 : Semaphore 实现 互斥 与 连接池
查看>>
null值经过强转会怎样?
查看>>
Sharepoint学习笔记—Debug&TroubleShooting--Developer Dashboard的使用(3.向Assert and Critical Events段插入信息)...
查看>>
Sharepoint学习笔记—习题系列--70-573习题解析 -(Q147-Q150)
查看>>
Sublime Text 报“Pylinter could not automatically determined the path to lint.py
查看>>
Vue基础汇总
查看>>
[小技巧] gcc 编译选项-###
查看>>
0513课堂01 数组,数学函数,时间函数
查看>>
grunt对象之api
查看>>
《驻足思考》笔记
查看>>
全网最详细的Windows系统里PLSQL Developer 64bit的下载与安装过程(图文详解)
查看>>
Spark MLlib回归算法LinearRegression
查看>>
Hadoop MapReduce概念学习系列之mr的Shuffle(二十二)
查看>>