POJ 3659 再谈树形DP
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 ≤ 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 这道题卡了我挺久的,主要是还是沿用覆盖边的那个旧思想,通过这一题,明白了做树形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 ;
}
POJ 3659 再谈树形DP的更多相关文章
- 再谈树形dp
上次说了说树形dp的入门 那么这次该来一点有难度的题目了: UVA10859 Placing Lampposts 给定一个n个点m条边的无向无环图,在尽量少的节点上放灯,使得所有边都与灯相邻(被灯照亮 ...
- poj 2324 Anniversary party(树形DP)
/*poj 2324 Anniversary party(树形DP) ---用dp[i][1]表示以i为根的子树节点i要去的最大欢乐值,用dp[i][0]表示以i为根节点的子树i不去时的最大欢乐值, ...
- POJ - 3162 Walking Race 树形dp 单调队列
POJ - 3162Walking Race 题目大意:有n个训练点,第i天就选择第i个训练点为起点跑到最远距离的点,然后连续的几天里如果最远距离的最大值和最小值的差距不超过m就可以作为观测区间,问这 ...
- POJ 2486 Apple Tree(树形DP)
题目链接 树形DP很弱啊,开始看题,觉得貌似挺简单的,然后发现貌似还可以往回走...然后就不知道怎么做了... 看看了题解http://www.cnblogs.com/wuyiqi/archive/2 ...
- POJ 3162.Walking Race 树形dp 树的直径
Walking Race Time Limit: 10000MS Memory Limit: 131072K Total Submissions: 4123 Accepted: 1029 Ca ...
- POJ 1655.Balancing Act 树形dp 树的重心
Balancing Act Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 14550 Accepted: 6173 De ...
- 再探树形dp
随着校oj终于刷进了第一页,可以不用去写那些水题了,开始认真学习自己的东西,当然包括文化课.努力.. 这道题呢是道树形dp,可看到了根本就不知道怎么写思考过程: 5min 终于看懂了题 画了样例的图把 ...
- POJ 2342 - Anniversary party - [树形DP]
题目链接:http://poj.org/problem?id=2342 Description There is going to be a party to celebrate the 80-th ...
- POJ 2152 Fire (树形DP,经典)
题意:给定一棵n个节点的树,要在某些点上建设消防站,使得所有点都能够通过某个消防站解决消防问题,但是每个点的建站费用不同,能够保证该点安全的消防站的距离上限也不同.给定每个点的建站费用以及最远的消防站 ...
随机推荐
- 005-PHP函数输出一行内容
<?php function printBold($inputText) //定义function printBold() { print("<B>" . $in ...
- 微信扫码登陆(JAVA)
在web端用到weChat扫码登录,在手机扫码登陆成功后,跳转到相应的界面. 1.第一步请求code 调用接口:https://open.weixin.qq.com/connect/qrconnect ...
- [题解] LuoguP5666 树的重心
这个题......确实是CSPNOIP题qwq 感觉猜到一个性质就差不多了,首先,对于一棵树,随便拎一个节点\(rt\)当根节点,那么他的重心一定在\(rt\)的重儿子里,进一步的,可以发现重心一定在 ...
- 一文详解scala泛型及类型限定
今天知识星球球友,微信问浪尖了一个spark源码阅读中的类型限定问题.这个在spark源码很多处出现,所以今天浪尖就整理一下scala类型限定的内容.希望对大家有帮助. scala类型参数要点 1. ...
- NO3 cat-xargs-cp-mv-rm-find命令
·cat #查看文件内容 eg:cat oldboy.txt·xargs #从标准输入获取内容创建和执行命令 -n 加数字:分组 ·cp ...
- [洛谷Luogu]P1803 线段覆盖问题
贪心想法题解的各位dalaodalaodalao都讲得很清楚了,在下就提供一种桶排的做法吧. 因为给出数据范围 0≤ai<bi≤10000000≤ai<bi≤10000000≤ai< ...
- 十四、SAP中定义自定义变量
一.利用关键字TYPE定义类型,然后在定义此类型的变量,代码如下: 二.效果如下:
- T_SQL 将一列多行数据合并为一行
SQL Server在进行数据迁移和报表处理的时候会遇到将一列多行数据拼接为一个字符串的情况,为了处理这个问题,在网上找了一些相关的资料,提供两种方法,供遇到类似问题的朋友们参考,也借此加深自己的印象 ...
- [转]SparkSQL的自适应执行---Adaptive Execution
1 背景 本文介绍的 Adaptive Execution 将可以根据执行过程中的中间数据优化后续执行,从而提高整体执行效率.核心在于两点 执行计划可动态调整 调整的依据是中间结果的精确统计信息 2 ...
- 实验吧-杂项-MD5之守株待兔(时间戳&python时间戳函数time.time())
其实也有点蒙圈,因为从没做过和时间戳有关的题. 打开网站,将系统密钥解密得到一串值,而自己的密钥解密是空的,既然说是要和系统匹配,就把解密得到的值以get方式送出去. 但是发现还是在自己的密钥也发生了 ...