hdu2196 树形dp
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=2196
总算彻底理解这个题了 =.=
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=; struct Edge
{
int v;
int len;
int next;
} edge[maxn<<]; int head[maxn];
int fm[maxn],fn[maxn]; ///最远距离,以及对应的子树的序号
int sm[maxn],sn[maxn]; ///次远距离,以及其对应的子树
int k; void addedge(int u,int v,int l)
{
edge[k].v=v;
edge[k].len=l;
edge[k].next=head[u];
head[u]=k++; edge[k].v=u;
edge[k].len=l;
edge[k].next=head[v];
head[v]=k++;
} void dfs1(int u,int p) ///第一次dfs找到子树种最大的长度,和最大长度的子树的序号
{
fm[u]=; ///初始化
sm[u]=;
for(int i=head[u]; i!=-; i=edge[i].next)
{
int v=edge[i].v;
if(v==p) continue;
dfs1(v,u);
if(edge[i].len+fm[v]>sm[u])
{
sm[u]=edge[i].len+fm[v];
sn[u]=v;
if(sm[u]>fm[u])
{
swap(fm[u],sm[u]);
swap(fn[u],sn[u]);
}
}
}
} void dfs2(int u,int p)
{
for(int i=head[u]; i!=-; i=edge[i].next)
{
int v=edge[i].v;
if(v==p) continue;
if(v==fn[u])
{
if(edge[i].len+sm[u]>sm[v])
{
sm[v]=edge[i].len+sm[u];
sn[v]=u; ///开始没懂为什么还要记录结点
if(sm[v]>fm[v]) ///更新的目的就是可以找到从子树来的最大值,不记录有时候找的是次大值
{
swap(fm[v],sm[v]);
swap(fn[v],sn[v]);
}
}
}
else
{
if(edge[i].len+fm[u]>sm[v])
{
sm[v]=edge[i].len+fm[u];
sn[v]=u;
if(sm[v]>fm[v])
{
swap(fm[v],sm[v]);
swap(fn[v],sn[v]);
}
}
}
dfs2(v,u);
}
} int main()
{
int n;
while(scanf("%d",&n)==)
{
memset(head,-,sizeof(head));
k=;
int x,l;
for(int i=; i<=n; i++)
{
scanf("%d%d",&x,&l);
addedge(i,x,l);
}
dfs1(,-); ///随便选一点作为树根,那么他的父亲结点就设为-1
dfs2(,-); ///所以换成dfs1(2,-1),dfs2(2,-1) 也是可以的
for(int i=; i<=n; i++)
printf("%d\n",fm[i]);
}
return ;
}
hdu2196 树形dp的更多相关文章
- hdu2196 树形dp经典|树的直径
/* 两种做法 1.求出树直径v1,v2,那么有一个性质:任取一点u,树上到u距离最远的点必定是v1或v2 那么可以一次dfs求树v1 第二次求dis1[],求出所有点到v1的距离,同时求出v2 第三 ...
- hdu2196树形dp
有一棵树,找每个节点所能到达的最远距离是多少 dis[u][0]正向最大距离 dis[u][1]正向次大距离 dis[u][2]反向最大距离 先一边dfs求出每个节点的正向最大距离(就是 ...
- Computer(HDU2196+树形dp+树的直径)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2196 题目: 题意:有n台电脑,每台电脑连接其他电脑,第i行(包括第一行的n)连接u,长度为w,问你每 ...
- hdu-2196 树形dp 求一个树中所有节点能到达的最远距离f[i] (其实也不难嘛!)
#include <bits/stdc++.h> using namespace std; ; struct T { int to; int w; }; vector < vecto ...
- 【树形dp小练】HDU1520 HDU2196 HDU1561 HDU3534
[树形dp]就是在树上做的一些dp之类的递推,由于一般须要递归处理.因此平庸情况的处理可能须要理清思路.昨晚開始切了4题,作为入门训练.题目都很easy.可是似乎做起来都还口以- hdu1520 An ...
- HDU2196 Computer(树形DP)
和LightOJ1257一样,之前我用了树分治写了.其实原来这题是道经典的树形DP,感觉这个DP不简单.. dp[0][u]表示以u为根的子树中的结点与u的最远距离 dp[1][u]表示以u为根的子树 ...
- HDU5834 Magic boy Bi Luo with his excited tree(树形DP)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5834 Description Bi Luo is a magic boy, he also ...
- Codeforces 543D Road Improvement(树形DP + 乘法逆元)
题目大概说给一棵树,树的边一开始都是损坏的,要修复一些边,修复完后要满足各个点到根的路径上最多只有一条坏的边,现在以各个点为根分别求出修复边的方案数,其结果模1000000007. 不难联想到这题和H ...
- POJ3162 Walking Race(树形DP+尺取法+单调队列)
题目大概是给一棵n个结点边带权的树,记结点i到其他结点最远距离为d[i],问d数组构成的这个序列中满足其中最大值与最小值的差不超过m的连续子序列最长是多长. 各个结点到其他结点的最远距离可以用树形DP ...
随机推荐
- RHEL7 CentOS7 检查查看精简指令
RHEL7 CentOS7 检查查看精简指令: //////////////////////////检查查看精简指令://///////////////////////////// ///////// ...
- [转]eclipse重新编译
Eclipse打开时并不重新生成class文件,这就造成了eclipse找不到需要的class文件从而不能正常编译工程中的其他代码.此时就需要重新编译工程. 单击Project菜单,选择Clean菜单 ...
- gif工具 - ScreenToGif
之前我介绍过LiceCap这款制作gif的软件,但是那个软件的获取方式较为麻烦,并且有时候可能在不同的设备上会表现效果有所不同,这里将要介绍的软件我认为还是非常不错的,我们可以在ScreenToGif ...
- JQuery中$.ajax()方法参数详解(转载)
url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. type: 要求为String类型的参数,请求方式(post或get)默认为get.注意其他http请求方法,例如put和 ...
- code::blocks编译出错
问题描述: 在windows xp 上编译的cbp项目(已经生成.obj文件),放到fedora上无法顺利编译.(build) collect2:error: ld returned 1 exit s ...
- [Unity3D]引擎学习之注意事项(持续更新中)
调试相关 如果是想在触发粒子系统效果的时候播放声音(比如爆炸的特殊发生时也播放声音),则需要将爆炸效果的粒子系统保持为Prefab后,添加Audio Source组件,在组件中添加声音文件并且确保pl ...
- JS各种方法
一.JS(去掉前后空格或去掉所有空格)的用法 1.去掉字符串前后所有空格:代码如下: function Trim(str) { return str.replace(/(^\s*)|(\s*$)/g, ...
- QQ空间HD(6)-实现自定义的选项卡切换效果
DJTabbarButton.m #import "DJTabbarButton.h" @implementation DJTabbarButton - (instancetype ...
- CSS-dl+dt+dd的应用(非常实用)
http://smallpig301.blog.163.com/blog/static/9986093201010262499229/
- vi 常用命令
1.关于退出 :wq! ----强制保存退出 :wq ---- 保存退出 ZZ ---- 作用和:wq一样,(注意Z是大写的,并且不是在命令模式) :q ---- 退出 :q! --- 强 ...