题意:求树中距离每个节点的最大距离。

解题关键:两次dfs,第一次从下向上dp求出每个节点子树中距离其的最大距离和不在经过最大距离上的子节点上的次大距离(后序遍历),第二次从上而下dp求出其从父节点过来的最大距离(先序遍历).

如果vi不是u最长距离经过的节点,$d[{v_i}][2] = dist[{v_i}][u] + \max (d[u][0],d[u][2])$;
如果vi是u最长距离经过的节点,$d[{v_i}][2] = dist[{v_i}][u] + \max (d[u][1],d[u][2]);$

最终答案即是从下而来和从上而来的距离的最大值。

取最大值和次大值时的>=和>是无所谓的,都可以过

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+;
int head[maxn],tot,d[maxn][],longest[maxn];
struct edge{
int to;
int nxt;
int w;
}e[maxn<<];
void add_edge(int u,int v,int w){
e[tot].to=v;
e[tot].w=w;
e[tot].nxt=head[u];
head[u]=tot++;
} int dfs1(int u,int fa){//返回子树最大距离
for(int i=head[u];i!=-;i=e[i].nxt){
int v=e[i].to;
if(v==fa) continue;
int tmp=dfs1(v,u);
if(d[u][]<tmp+e[i].w){
longest[u]=v;
d[u][]=d[u][];
d[u][]=tmp+e[i].w;
}else if(d[u][]<tmp+e[i].w){//求次大距离必须加else if
d[u][]=tmp+e[i].w;
}
}
return d[u][];
} void dfs2(int u,int fa){
for(int i=head[u];i!=-;i=e[i].nxt){
int v=e[i].to;
if(v==fa) continue;
if(v==longest[u]) d[v][]=max(d[u][],d[u][])+e[i].w;
else d[v][]=max(d[u][],d[u][])+e[i].w;
dfs2(v,u);
}
} int main(){
int n;
ios::sync_with_stdio();
cin.tie();
cout.tie();
while(cin>>n){
tot=;
memset(d,,sizeof d);
memset(head,-,sizeof head);
memset(longest,,sizeof longest);
int a,b;
for(int i=;i<=n;i++){
cin>>a>>b;
add_edge(i,a,b);
add_edge(a,i,b);
}
dfs1(,-);
dfs2(,-);
for(int i=;i<=n;i++){
cout<<max(d[i][],d[i][])<<"\n";
}
}
return ;
}

最优写法:

不需要记录longest,只要d[v][0]+e[i].w==d[u][0],此时即可取次大距离。

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+;
int head[maxn],tot,d[maxn][];
struct edge{
int to;
int nxt;
int w;
}e[maxn<<];
void add_edge(int u,int v,int w){
e[tot].to=v;
e[tot].w=w;
e[tot].nxt=head[u];
head[u]=tot++;
} void dfs1(int u,int fa){//返回子树最大距离
for(int i=head[u];i!=-;i=e[i].nxt){
int v=e[i].to;
if(v==fa) continue;
dfs1(v,u);
int tmp=d[v][]+e[i].w;
if(d[u][]<=tmp){
d[u][]=d[u][];
d[u][]=tmp;
}else if(d[u][]<tmp){//求次大距离必须加else if
d[u][]=tmp;
}
}
} void dfs2(int u,int fa){
for(int i=head[u];i!=-;i=e[i].nxt){
int v=e[i].to;
if(v==fa) continue;
if(d[u][]==d[v][]+e[i].w) d[v][]=max(d[u][],d[u][])+e[i].w;
else d[v][]=max(d[u][],d[u][])+e[i].w;
dfs2(v,u);
}
} int main(){
int n;
ios::sync_with_stdio();
cin.tie();
cout.tie();
while(cin>>n){
tot=;
memset(d,,sizeof d);
memset(head,-,sizeof head);
int a,b;
for(int i=;i<=n;i++){
cin>>a>>b;
add_edge(i,a,b);
add_edge(a,i,b);
}
dfs1(,-);
dfs2(,-);
for(int i=;i<=n;i++){
cout<<max(d[i][],d[i][])<<"\n";
}
}
return ;
}

[hdu2196]Computer树的直径的更多相关文章

  1. 【HDU 2196】 Computer(树的直径)

    [HDU 2196] Computer(树的直径) 题链http://acm.hdu.edu.cn/showproblem.php?pid=2196 这题可以用树形DP解决,自然也可以用最直观的方法解 ...

  2. hdu 2196 Computer 树的直径

    Computer Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem ...

  3. HDOJ 2196 Computer 树的直径

    由树的直径定义可得,树上随意一点到树的直径上的两个端点之中的一个的距离是最长的... 三遍BFS求树的直径并预处理距离....... Computer Time Limit: 1000/1000 MS ...

  4. codeforces GYM 100114 J. Computer Network 无相图缩点+树的直径

    题目链接: http://codeforces.com/gym/100114 Description The computer network of “Plunder & Flee Inc.” ...

  5. codeforces GYM 100114 J. Computer Network tarjan 树的直径 缩点

    J. Computer Network Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Des ...

  6. HDU 2196.Computer 树形dp 树的直径

    Computer Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  7. [J]computer network tarjan边双联通分量+树的直径

    https://odzkskevi.qnssl.com/b660f16d70db1969261cd8b11235ec99?v=1537580031 [2012-2013 ACM Central Reg ...

  8. computer(树形dp || 树的直径)

    Computer Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  9. hdu2196 树的直径 + bfs

    //Accepted 740 KB 15 ms //树的直径 //距离一个顶点最远的点一定是树的直径的一个端点 #include <cstdio> #include <cstring ...

随机推荐

  1. spring4 maven3 mybatis

    1 新建maven工程 http://www.cnblogs.com/quanyongan/archive/2013/04/21/3033838.html 如果在第三步中出现错误,比如类似: Coul ...

  2. wpf自定义colorpicker

    自定义colorpicker <ObjectDataProvider MethodName="GetType" ObjectType="{x:Type system ...

  3. Yii的权限管理rbac

    1.首先我们要在配置文件的组件(component)里面配置一下 Rbac 在对应项目下的config/main.php或者config/main-local.php下添加 'authManager' ...

  4. 初识python轻量web框架flask

    1.使用pip安装Python包 大多数Python包都使用pip实用工具安装,使用pyvenv创建的虚拟环境会自动安装pip. 1.使用pip安装Flask(其它Python包同理) pip ins ...

  5. Eclipse打jar包的方法

    1.准备主清单文件 “MANIFEST.MF” Manifest-Version: 1.0 Class-Path: lib/commons-codec.jar lib/commons-httpclie ...

  6. 随机生成指定长度的密码之---Random

    随机生成指定长度的密码思路: 1.密码中可能包含字母,数字,特殊符号,为了区别分别定义常量 2.随机生成密码,自然想到要用到java.util.Random 类 3.定义一个带两个参数的方法,1跟2, ...

  7. Spring Boot 支持多种外部配置方式

    Spring Boot 支持多种外部配置方式 http://blog.csdn.net/isea533/article/details/50281151 这些方式优先级如下: 命令行参数 来自java ...

  8. Spring项目中使用jackson序列化key为对象Map

    1.注入ObjectMapper2.注册类HistoricTaskInstance的序列化和反序列化类HistoricTaskInstanceKeySerializer,HistoricTaskIns ...

  9. Flask中的内置session

    Flask中的Session非常的奇怪,他会将你的SessionID存放在客户端的Cookie中,使用起来也非常的奇怪 1. Flask 中 session 是需要 secret_key 的 from ...

  10. 《程序员代码面试指南》第八章 数组和矩阵问题 数组的partition 调整

    题目 数组的partition 调整 java代码 package com.lizhouwei.chapter8; /** * @Description: 数组的partition 调整 * @Aut ...