Cell Phone Network
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 5325   Accepted: 1886

Description

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 ≤ NA ≠ B) there is a sequence of adjacent pastures such that 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

这道题卡了我挺久的,主要是还是沿用覆盖边的那个旧思想,通过这一题,明白了做树形DP最重要就是找准状态有哪几种。像之前那个覆盖边的题目,状态就两种,顶多算三种吧,己有子无的最优,己有子有的最优,己无子有的最优,。。。不过前两种完全可以合并成一个,通过min函数挑选出最优
但是这个题目,相对于前三种,就多了一个状态,己无子无,这个是可以存在的,因为只需要覆盖点,所以在搜索过程中,完全可以出现这种情况
所以为了照顾最后一种,只能增加一个dp[i][0] 即为i未放点,且i未被覆盖(说明子未放点)的最优值。。。当然这个肯定不是最优的,但是这个量为父亲挑选起了很大作用
故dp[i][0]+=dp[son][2];
(己有的最优值)dp[i][1]+=dp[son][0],dp[son][1],dp[son][2]的最小
(己无得最优)dp[i][2]+=dp[i][1],dp[i][2]的最小(此式不完全正确,下面分析)
请特别注意,如果dp[i][2]选的全部都是儿子的dp[i][2],意味着不满足条件,一定至少要儿子有一个点为dp[son][1];
我当时智商拙计,想到了这里,还是没想明白怎么判断是否取了不满足的条件
后来原来是统计下所有dp[son][1]>dp[son][2]用一个tmin记录下dp[son][1]-dp[son][2]的最小值,并且用一个bool变量判断是否有dp【son】【1】(只需要儿子中的一个dp[son][1]<=dp[son][2]即可)。。。如果没有dp【son】【1】,则dp[i][2]+=tmin;即可求得最优 还有,处理最底下的叶子的时候,dp[叶子][2]按定义来说好像是0,但是这个又不能成立,可以虚拟一个虚点连接叶子用来覆盖,但不计数,使得dp[叶子][2]=1;
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#define N 10005
#define INF 99999999
using namespace std;
vector<int> v[N];
int dp[N][];
bool vis[N];
void dfs(int root)
{
vis[root]=;
dp[root][]=dp[root][]=;
dp[root][]=;
int temp=,tmin=INF;
bool flag=false,ff=false;
for (int i=;i<v[root].size();i++)
{
int x=v[root][i];
if (vis[x]) continue;
dfs(x);
dp[root][]+=min(dp[x][],min(dp[x][],dp[x][]));
dp[root][]+=dp[x][];
dp[root][]+=min(dp[x][],dp[x][]);
if (dp[x][]>dp[x][]) tmin=min(tmin,dp[x][]-dp[x][]);
else flag=true;
ff=true;
}
if (!flag && ff) dp[root][]+=tmin;
if (!ff) dp[root][]=;//叶子情况,但是此时脑子里虚拟出一个不存在的点来覆盖叶子点,使得dp[root][2]能顺理成章的=1;
}
int main()
{
int n;
while (scanf("%d",&n)!=EOF)
{
int a,b;
int i,j;
for (i=;i<n;i++)
{
scanf("%d%d",&a,&b);
v[a].push_back(b);
v[b].push_back(a);
}
memset(vis,,sizeof vis);
dfs();
printf("%d\n",min(dp[][],dp[][]));
}
return ;
}

最新文章

  1. ObjectAnimator属性动画应用demo
  2. html ul li的学习
  3. 在不知道json格式的情况下如何使用cjson进行解析
  4. .net添加下拉框
  5. 转!!!Mybatis实现数据的增删改查(CRUD)
  6. 小白日记10:kali渗透测试之端口扫描-UDP、TCP、僵尸扫描、隐蔽扫描
  7. 命令ls
  8. Java操作hbase总结
  9. A记录、CNAME记录、MX记录
  10. 在Struts2中集成Spring详细讲解
  11. Mybatis包分页查询java公共类
  12. WIN7 嵌入式系统安装教程 Windows Embedded Standard 2011 安装
  13. windows之自动化在虚拟机部署操作系统并自带python环境
  14. db2 删除过期的日志和备份文件(转)
  15. [转载]jdk环境变量配置方法
  16. error MSB6006: &quot;CL.exe&quot; exited with code -1073741819.
  17. Java中遍历字符串toCharArray()和charAt()效率比较
  18. Vquery PHP 简单爬虫类
  19. Kettle中调用用户自定义的jar包
  20. delphi sqlsever 实现存在则更新,不存在

热门文章

  1. 爬虫(十六):Scrapy框架(三) Spider Middleware、Item Pipeline
  2. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 字体图标(Glyphicons):glyphicon glyphicon-fast-forward
  3. 一道算法题加深我对C++中map函数的理解
  4. 完全卸载(删除)mac下自带的php
  5. 3D打印技术的火爆,真的会让传统模具行业没落吗?
  6. 蓝桥杯-机器繁殖 第6届C语言C组决赛第4题
  7. 本机无oracle,远程连接
  8. 自定义spark UDAF
  9. Java中的static关键字和new关键字作用介绍
  10. Channel详解