hdu2196树形dp
有一棵树,找每个节点所能到达的最远距离是多少
dis[u][0]正向最大距离 dis[u][1]正向次大距离 dis[u][2]反向最大距离
先一边dfs求出每个节点的正向最大距离(就是向下)和次向最大距离,以及longest记录下当前节点的正向最大距离路径的子节点(为了第二遍dfs,判断这一条路是不是正向最大距离)
再进行第二遍dfs,v是u 的子节点,如果v在u的正向最大距离路径里(即longest[u]=v)那么v的最大反向距离就是max(u的最大反向距离,u的正向次大距离)+w【u】【v】
如果v不在u 的正向最大距离路径里,那么v的最大反向距离就是max(u的最大反向距离,u的正向最大距离)+w【u】【v】
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<cstdio>
#include<cassert>
#include<iomanip>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define pi acos(-1)
#define ll long long
#define mod 1000000007
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; const double g=10.0,eps=1e-;
const int N=+,maxn=+,inf=0x3f3f3f; struct edge{
int to,Next,w;
}e[N*];
int cnt,Head[N];
int longest[N],dis[N][];//0正向最大距离,1正向次大距离,2反向最大距离
void add(int u,int v,int w)
{
e[cnt].to=v;
e[cnt].w=w;
e[cnt].Next=Head[u];
Head[u]=cnt++;
}
int dfs1(int u,int fa)//返回u的正向最大距离,fa是u的父节点
{
if(dis[u][]>)return dis[u][];
dis[u][]=dis[u][]=dis[u][]=longest[u]=;
for(int i=Head[u];~i;i=e[i].Next)
{
int v=e[i].to;
if(v==fa)continue;
if(dis[u][]<dfs1(v,u)+e[i].w)//v是u的最大距离中的一个子节点
{
longest[u]=v;
dis[u][]=max(dis[u][],dis[u][]);//此时dis[u][0]就是一个可能的次大节点了
dis[u][]=dfs1(v,u)+e[i].w;
}
else if(dis[u][]<dfs1(v,u)+e[i].w)
dis[u][]=max(dis[u][],dfs1(v,u)+e[i].w);
}
return dis[u][];
}
int dfs2(int u,int fa)
{
for(int i=Head[u];~i;i=e[i].Next)
{
int v=e[i].to;
if(v==fa)continue;
if(longest[u]==v)dis[v][]=max(dis[u][],dis[u][])+e[i].w;
else dis[v][]=max(dis[u][],dis[u][])+e[i].w;
dfs2(v,u);
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie();
int n;
while(cin>>n){
cnt=;
memset(Head,-,sizeof Head);
memset(dis,-,sizeof dis);
memset(longest,-,sizeof longest);
for(int i=;i<=n;i++)
{
int v,w;
cin>>v>>w;
add(i,v,w);
add(v,i,w);
}
dfs1(,-);
dfs2(,-);
for(int i=;i<=n;i++)
cout<<max(dis[i][],dis[i][])<<endl;
}
return ;
}
/*
longest[i]=j代表i在子树中的最大距离经过了j节点
*/
树形dp
hdu2196树形dp的更多相关文章
- hdu2196 树形dp经典|树的直径
/* 两种做法 1.求出树直径v1,v2,那么有一个性质:任取一点u,树上到u距离最远的点必定是v1或v2 那么可以一次dfs求树v1 第二次求dis1[],求出所有点到v1的距离,同时求出v2 第三 ...
- Computer(HDU2196+树形dp+树的直径)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2196 题目: 题意:有n台电脑,每台电脑连接其他电脑,第i行(包括第一行的n)连接u,长度为w,问你每 ...
- hdu2196 树形dp
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=2196 Problem Description A school bought the fi ...
- 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 ...
随机推荐
- Oracle获取当前session ID的方法
1.使用v$mystat视图获取当前session的ID select sid from v$mystat; 2.使用userenv内部函数获取当前session的ID select userenv( ...
- CDOJ 1502 string(简单贪心)
题目大意:原题链接 相邻两个字母如果不同,则可以结合为前一个字母,如ac可结合为a.现给定一个字符串,问结合后最短可以剩下多少个字符串 解体思路:简单贪心 一开始读题时,就联想到之前做过的一道题,从后 ...
- javaWeb 使用线程池+队列解决"订单并发"问题
解决方式:使用线程池+队列 项目基于Spring,如果不用spring需要自己把 ThreadPoolManager.java 改成单例模式 1.写一个Controller(Spring mvc) / ...
- 多媒体文件格式分析 MP3文件结构及编解码流程
多媒体文件格式分析 http://blog.csdn.net/taniya001/article/details/7962864 多媒体文件格式分析 MP3文件结构及编解码流程 http://www. ...
- 3.1、Ubuntu系统中jmeter的安装和目录解析
以下内容亲测,如果不对的地方,欢迎留言指正,不甚感激.^_^祝工作愉快^_^ Jmeter是一个非常好用的压力测试工具. Jmeter用来做轻量级的压力测试,非常合适,只需要十几分钟,就能把压力测 ...
- JMeter的安装和目录解析
Ubuntu系统中jmeter的安装和目录解析 作为一个Linux新手,在使用jdk时,或许会安装配置多次仍然导致无法使用情况(如无法登录系统等),请按如下步骤一步一步安装并配置 相关软件下载地址 J ...
- SDUT oj 2610
/*题目大意:输入一序列n个数字,然后输入m个询问,每个询问包含左边区间和右边区间,还有a和b,问你这个区间内有几个数大于等于a且小于等于b 做法:树状数组,先求出这个区间内有几个数小于a,然后求这个 ...
- C++类中成员变量的初始化总结(转帖)
本文转自:C++类中成员变量的初始化总结 1. 普通的变量: 一般不考虑啥效率的情况下 可以在构造函数中进行赋值.考虑一下效率的可以再构造函数的初始化列表中进行. 1 class CA ...
- 在VMware中使用Nat方式设置静态IP
为了在公司和家中不改变ip,所以采用vm的NAT模式来设置静态ip 1.vm采用NAT模式联网 2.编辑vm虚拟机设置 3.查看该网段的网关 可以看出网关为192.168.44.2,然后开始设置静态i ...
- 20145329《Java程序设计》第八周学习总结
教材学习内容总结 日志 1.java.util.logging包提供了日志功能相关类与接口. 2.使用日志的起点是Logger类,Longer类的构造函数标示为protected,不同包的类药取得Lo ...