紫书 例题 9-14 UVa 1218 (树形dp)
这道题有个初始值设成1e9, 然后这个值是要加很多次的,然后就会溢出变成负数,
然后就一直WA, 找这个bug找了一个小时……以后不能随便这样设那么大,
要考虑会不会加很多次然后溢出。
讲一下思路。
首先对于当前节点u,可以分三种情况。
一种是当前节点是服务器,一种是节点的父亲是服务器,一种是节点的儿子是服务器。
不可能都不是服务器,因为如果这样的话u自己就没有服务器相连。
设本身是服务器的为d(u, 0),父亲是服务器为d(u, 1),儿子是服务器是d(u, 2)
那么我们可以写出转移方程
d(u, 0):此时u的儿子可以是服务器也可以不是服务器,所以d[u][0] = sum{min(d(v, 0),d(v, 1)) | v是u的儿子} + 1(本身)
d(u, 1):此时u的儿子全部都不是服务器,因为父亲已经是,只能和一个服务器相连。,所以d(u, 1) = sum{d(v, 2)| v是u的儿子}
d(u, 2):此时u的节点中一定有且只有一个儿子有服务器,所以我们可以枚举这个儿子是哪一个,设这个儿子是q, 其他的所有儿子是p, 那么d(u, 2) = min(d(q, 0) + sum(d(p, 2)))
但是这样非常的耗时间,我们可以利用前面的式子代换一下。
我们观察 sum(d(p, 2)), p是除了q以外的所有儿子,所以可以用所有儿子的值减去q的值,
也就是sum(d(p, 2)) = sum(d(v, 2)) - d(q, 2) = d(u, 1) - d(q, 2)。所以枚举q取最小的就好了。
以0为根节点,最后输出min(d(0, 0), d(0, 2)), 根节点没有父节点,所以d(0, 1)不理他
#include<cstdio>
#include<vector>
#include<algorithm>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
using namespace std;
const int MAXN = 11234;
int d[MAXN][3], n;
vector<int> g[MAXN];
void dfs(int u, int fa)
{
d[u][1] = 0; d[u][0] = 1;
if(g[u].size() == 1 && fa != -1) return;
REP(i, 0, g[u].size())
{
int v = g[u][i];
if(v == fa) continue;
dfs(v, u);
d[u][1] += d[v][2];
d[u][0] += min(d[v][1], d[v][0]);
}
REP(i, 0, g[u].size())
{
int v = g[u][i];
if(v == fa) continue;
d[u][2] = min(d[u][2], d[u][1] - d[v][2] + d[v][0]);
}
}
int main()
{
while(~scanf("%d", &n))
{
REP(i, 0, n) g[i].clear(), d[i][2] = MAXN + 1;
REP(i, 0, n - 1)
{
int a, b;
scanf("%d%d", &a, &b);
a--; b--;
g[a].push_back(b);
g[b].push_back(a);
}
dfs(0, -1);
printf("%d\n", min(d[0][0], d[0][2]));
scanf("%d", &n);
}
return 0;
}
紫书 例题 9-14 UVa 1218 (树形dp)的更多相关文章
- 紫书 例题 11-13 UVa 10735(混合图的欧拉回路)(最大流)
这道题写了两个多小时-- 首先讲一下怎么建模 我们的目的是让所有点的出度等于入度 那么我们可以把点分为两部分, 一部分出度大于入度, 一部分入度大于出度 那么显然, 按照书里的思路,将边方向后,就相当 ...
- 紫书 例题8-3 UVa 1152(中途相遇法)
这道题要逆向思维, 就是求出答案的一部分, 然后反过去去寻找答案存不存在. 其实很多其他题都用了这道题目的方法, 自己以前都没有发现, 这道题专门考这个方法.这个方法可以没有一直往下求, 可以省去很多 ...
- 紫书 例题8-12 UVa 12627 (找规律 + 递归)
紫书上有很明显的笔误, 公式写错了.g(k, i)的那个公式应该加上c(k-1)而不是c(k).如果加上c(k-1)那就是这一次 所有的红气球的数目, 肯定大于最下面i行的红气球数 我用的是f的公式, ...
- 紫书 例题8-4 UVa 11134(问题分解 + 贪心)
这道题目可以把问题分解, 因为x坐标和y坐标的答案之间没有联系, 所以可以单独求两个坐标的答案 我一开始想的是按照左区间从小到大, 相同的时候从右区间从小到大排序, 然后WA 去uDebug找了数据 ...
- 紫书 例题8-17 UVa 1609 (构造法)(详细注释)
这道题用构造法, 就是自己依据题目想出一种可以得到解的方法, 没有什么规律可言, 只能根据题目本身来思考. 这道题的构造法比较复杂, 不知道刘汝佳是怎么想出来的, 我想的话肯定想不到. 具体思路紫书上 ...
- 紫书 例题 9-5 UVa 12563 ( 01背包变形)
总的来说就是价值为1,时间因物品而变,同时注意要刚好取到的01背包 (1)时间方面.按照题意,每首歌的时间最多为t + w - 1,这里要注意. 同时记得最后要加入时间为678的一首歌曲 (2)这里因 ...
- uva 1292 树形dp
UVA 1292 - Strategic game 守卫城市,城市由n个点和n-1条边组成的树,要求在点上安排士兵,守卫与点相连的边.问最少要安排多少士兵. 典型的树形dp.每一个点有两个状态: dp ...
- UVA 10859 树形DP
很明显的树形DP了,设状态dp[i][0],dp[i][1].枚举子节点放或不放的两种状态. 在此学到一种不同于一般处理的方法,题目要求被两灯照亮的边尽量多,反过来即被一灯照亮的尽量少设为e.又需要的 ...
- 紫书 例题 9-12 UVa 12186 (树形dp)
这道题还是比较简单的,对于当前节点,算出每个儿子需要的人数 然后再算出当前节点需要多少个人数,然后排个序加上去就好了. #include<cstdio> #include<vecto ...
随机推荐
- ASP.NET Web开发技术的深入总结
[IT168技术]在国内.Net开发这个环境里, 中小型公司.或者大公司但主营业务不是软件开发里面的软件小团队.针对.Net开发者的要求都是十项全能型的全才, 能做的了从前台页面展现到最后数据存储的全 ...
- 数据可视化之Processing【1】
说Processing之前得先说一下数据可视化. 数据可视化--顾名思义.是关于数据之视觉表现形式的研究,将数据用其它方式表现出来,使之更直观, 更清晰,更easy分析和处理.常见的表达方式如word ...
- angularjs 指令2
<!DOCTYPE HTML> <html ng-app="myApp"> <head> <meta http-equiv="C ...
- ubuntu SDK 安装
纯净sdk安装1.地址-http://gmirror.org/#android-sdk-tools-only(国内镜像)2.下载到本地目录 ~/下载3.进入下载,解压 tar -zxvf androi ...
- Struts2标签库整理【完整】
转自:https://blog.csdn.net/chen_zw/article/details/8161230 Struts2标签库提供了主题.模板支持,极大地简化了视图页面的编写,而且,str ...
- [JZOJ3382] [NOIP2013模拟] 七夕祭 解题报告
Description 七夕节因牛郎织女的传说而被扣上了「情人节」的帽子.于是TYVJ今年举办了一次线下七夕祭.Vani同学今年成功邀请到了cl同学陪他来共度七夕,于是他们决定去TYVJ七夕祭游玩. ...
- 23.STL容器小结
- struts2连接mysql多表查询
下载地址:http://download.csdn.net/detail/qq_33599520/9786567 项目结构: 代码: package com.mstf.action; import j ...
- Spring MVC 核心架构图
架构图对应的DispatcherServlet核心代码如下: //前端控制器分派方法 protected void doDispatch(HttpServletRequest request, Htt ...
- asp.net导出execl和图片
个人常用导出execl方法: #region "导出文档" /// <summary> /// Export("application/ms-excel&qu ...