HDU 2136:Computer(树形DP)
http://acm.split.hdu.edu.cn/showproblem.php?pid=2196
Description
Hint: the example input is corresponding to this graph. And from the graph, you can see that the computer 4 is farthest one from 1, so S1 = 3. Computer 4 and 5 are the farthest ones from 2, so S2 = 2. Computer 5 is the farthest one from 3, so S3 = 3. we also get S4 = 4, S5 = 4.
Input
Output
Sample Input
5
1 1
2 1
3 1
1 1
Sample Output
3
2
3
4
4 题意:给出一棵树,求树中每个节点到树中任意其他节点的最大距离。
思路:想了挺久还是不会做,只能学习一下别人的了。http://blog.csdn.net/shuangde800/article/details/9732825
和之前那道水题完全天壤之别。
用两次dfs来求出最大的距离。第一次dfs是求出节点i的子树节点到i的最大距离,用dp[i][0]表示(从上往下)。第二次dfs是求出不在节点i的子树的节点中的其他节点到节点i的最大距离(从下往上),即到父节点的最大距离 + 父节点和该节点的w(父节点的最大距离的路径不能包含i,若包含要用次大距离),用dp[i][1]表示。答案就取max(dp[i][0], dp[i][1]).
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cmath>
#include <queue>
#include <vector>
using namespace std;
#define N 10010
struct node
{
int v, nxt, w;
}edge[N*];
int head[N], tot;
int dp[N][];
bool vis[N]; /*
dp[i][0],表示顶点为i的子树的,距顶点i的最长距离
dp[i][1],表示Tree(i的父节点)-Tree(i)的最长距离+i跟i的父节点距离
Tree(x)表示以x为根的子树
*/
void add(int u, int v, int w)
{
edge[tot].v = v;
edge[tot].w = w;
edge[tot].nxt = head[u];
head[u] = tot++;
edge[tot].v = u;
edge[tot].w = w;
edge[tot].nxt = head[v];
head[v] = tot++;
} void dfs1(int u) //回溯的时候找到各个节点子树距节点的最大距离
{
vis[u] = ;
for(int i = head[u]; ~i; i = edge[i].nxt) {
int v = edge[i].v, w = edge[i].w;
if(vis[v]) continue;
dfs1(v);
dp[u][] = max(dp[u][], w + dp[v][]);
}
} void dfs2(int u) //从上往下找不属于该节点子树的节点到该节点的最大距离,即从另一个方向找
{
vis[u] = ;
int ma1 = , ma2 = , tmp, v1, v2;
for(int i = head[u]; ~i; i = edge[i].nxt) { //从子节点到该节点父节点最大距离
int v = edge[i].v, w = edge[i].w;
if(vis[v]) continue;
tmp = dp[v][] + w;
if(tmp > ma1) {
ma2 = ma1, v2 = v1, ma1 = tmp, v1 = v;
} else if(tmp > ma2) {
ma2 = tmp, v2 = v;
}
} if(u != ) { //有父节点有兄弟的话,找从其他节点到父节点的最长距离
tmp = dp[u][];
int v = ; //这个时候一定是用dp[u][1],所以不受限制
if(tmp > ma1) {
ma2 = ma1, v2 = v1, ma1 = tmp, v1 = v;
} else if(tmp > ma2) {
ma2 = tmp, v2 = v;
}
} for(int i = head[u]; ~i; i = edge[i].nxt) {
int v = edge[i].v, w = edge[i].w;
if(vis[v]) continue;
if(v == v1) { //如果最长的距离的路径经过该节点,那么只能选次大的
dp[v][] = ma2 + w;
} else { //否则可以选最大的
dp[v][] = ma1 + w;
}
dfs2(v);
}
} int main()
{
int n;
while(~scanf("%d", &n)) {
memset(head, -, sizeof(head));
tot = ;
for(int i = ; i <= n; i++) {
int v, w;
scanf("%d%d", &v, &w);
add(i, v, w);
} memset(vis, , sizeof(vis));
memset(dp, , sizeof(dp));
dfs1();
memset(vis, , sizeof(vis));
dfs2(); for(int i = ; i <= n; i++) {
printf("%d\n", max(dp[i][], dp[i][]));
}
} return ;
}
HDU 2136:Computer(树形DP)的更多相关文章
- HDU 2196.Computer 树形dp 树的直径
Computer Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- HDU 2196 Computer 树形DP经典题
链接:http://acm.hdu.edu.cn/showproblem.php? pid=2196 题意:每一个电脑都用线连接到了还有一台电脑,连接用的线有一定的长度,最后把全部电脑连成了一棵树,问 ...
- HDU 2196 Computer 树形DP 经典题
给出一棵树,边有权值,求出离每一个节点最远的点的距离 树形DP,经典题 本来这道题是无根树,可以随意选择root, 但是根据输入数据的方式,选择root=1明显可以方便很多. 我们先把边权转化为点权, ...
- hdu 2196 Computer(树形DP)
Computer Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- hdu 2196 Computer 树形dp模板题
Computer Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total S ...
- hdu 2196 Computer(树形DP经典)
Computer Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- HDU 2196 Computer (树dp)
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=2196 给你n个点,n-1条边,然后给你每条边的权值.输出每个点能对应其他点的最远距离是多少 ...
- HDU - 2196(树形DP)
题目: A school bought the first computer some time ago(so this computer's id is 1). During the recent ...
- computer(树形dp || 树的直径)
Computer Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- hdu 6201 【树形dp||SPFA最长路】
http://acm.hdu.edu.cn/showproblem.php?pid=6201 n个城市都在卖一种书,该书的价格在i城市为cost[i],商人打算从某个城市出发到另一个城市结束,途中可以 ...
随机推荐
- pymongo使用总结
0. 何为pymongo pymongo是操作MongoDB的python模块 1.安装pymongo # easy_install pymongo 2.连接mongodb >>> ...
- javascript设计模式学习之九——命令模式
一.命令模式使用场景及定义 命令模式常见的使用场景是:有时候需要向某些对象发送请求,但是并不知道请求的接受者是谁,也不知道请求的具体操作是什么.此时希望用一种松耦合的方式来设计程序,使得请求的发送者和 ...
- C++Primer 第四章
//1.当我们对运算符进行重载的时候,其包括运算对象的类型和返回值的类型都是由该运算符定义的,但是运算对象的个数和优先级,结合律都是不能改变的 //2.当一个对象被用作右值的时候,用的是对象的值(内容 ...
- PostgreSQL Replication之第十二章 与Postgres-XC一起工作(6)
12.6 添加节点 Postgres-XC允许您在那个过程中的任何一个时间点添加新的服务器到计划中.所有您需要做的是按照我们之前演示的设置一个节点,并在 控制器上调用CREATE NODE.然后,该系 ...
- jvm内存设置
JVM有很多个内存管理命令,总体而言,分为两类: 1.-X开头的管理命令:这些选项在JDK升级时不会通知修改: 2.-XX开头的管理命令:这些选项不够稳定,所以建议少用. JVM参数的含义: 参数名称 ...
- 关于 static 的用途
1.三个作用 第一个作用是 隐藏 输出: Hello 所有未加static前缀的全局变量和函数都具有全局可见性,其它的源文件也能访问.此例中,a是全局变量,msg是函数,并且都没有加static前缀, ...
- ios blog
转得一个朋友的博客,大家可以看哈(主要时国外的) 主要分开发教程.示例项目.UI设计.问题解决几块. 开发教程: 即便过了入门阶段,还是要经常看看一些不错的实例教程. .http://mobile.t ...
- oracle ebs 采购订单关闭之PL/SQL实现方法
应客户需求,需要写个脚本,批量关闭Bonus Item类型的采购订单,在metalink上搜索到一些方法,但是都测试不通.原来需要将代码生成一个并发程序.下面是测试成功的代码. 1.首先创建一个存储过 ...
- 夺命雷公狗---DEDECMS----13dedecms首页的完成
我们的dedecms搭建起来后直接复制templets的目录复制一份,如下所示: 然后进入templets目录里面,然后再将default里面的东西都给干掉,然后将我们预先准备好的首页放进来,代码如下 ...
- linux中启动与终止lnmp的脚本
说是lnmp, 其实暂时只是 lnp, 因为还没有安装 mysql 这是脚本: #!/bin/bash function lnmpstart() { nginx /usr/local/php/bin/ ...