[hdu2196]Computer树的直径
题意:求树中距离每个节点的最大距离。
解题关键:两次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树的直径的更多相关文章
- 【HDU 2196】 Computer(树的直径)
[HDU 2196] Computer(树的直径) 题链http://acm.hdu.edu.cn/showproblem.php?pid=2196 这题可以用树形DP解决,自然也可以用最直观的方法解 ...
- hdu 2196 Computer 树的直径
Computer Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem ...
- HDOJ 2196 Computer 树的直径
由树的直径定义可得,树上随意一点到树的直径上的两个端点之中的一个的距离是最长的... 三遍BFS求树的直径并预处理距离....... Computer Time Limit: 1000/1000 MS ...
- codeforces GYM 100114 J. Computer Network 无相图缩点+树的直径
题目链接: http://codeforces.com/gym/100114 Description The computer network of “Plunder & Flee Inc.” ...
- codeforces GYM 100114 J. Computer Network tarjan 树的直径 缩点
J. Computer Network Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Des ...
- HDU 2196.Computer 树形dp 树的直径
Computer Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- [J]computer network tarjan边双联通分量+树的直径
https://odzkskevi.qnssl.com/b660f16d70db1969261cd8b11235ec99?v=1537580031 [2012-2013 ACM Central Reg ...
- computer(树形dp || 树的直径)
Computer Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- hdu2196 树的直径 + bfs
//Accepted 740 KB 15 ms //树的直径 //距离一个顶点最远的点一定是树的直径的一个端点 #include <cstdio> #include <cstring ...
随机推荐
- Windows操作系统远程Linux服务器传输文件方法(以EasyDSS云平台、EasyNVR上传部署为例)
本文转自博客:https://blog.csdn.net/black_3717/article/details/79769406 问题背景: 之前给客户部署我们一款EasyDSS云平台(配合EasyN ...
- EasyDSS高性能流媒体服务器前端重构(六)- webpack-dev-server 支持手机端访问
很多时候,前端开发的页面,不仅要在PC端测试效果, 还要在手机端测试效果. 在开发阶段, 我们以 webpack-dev-server 来启动浏览器, 打开正在开发的页面. webpack-dev-s ...
- php总结5——常量、文件上传
5.1常量 系统常量: PHP_OS 操作系统 PHP_VERSION php版本 PHP_SAPI 运行方式 自定义常量: define("常量名称"," ...
- angularJs自定义模块
<script type="text/javascript"> var myApp = angular.module("myApp",[]); my ...
- nginx高可用配置
可参考资料: http://www.cnblogs.com/holbrook/archive/2012/10/25/2738475.html http://blog.csdn.net/e4210834 ...
- webpack笔记1
1.设置多个入口起点 多用于提取公共类库 a.利用commonChunkPlugin const webpack= require('webpack'); const path = require(' ...
- 用户态文件系统fuse学习【转】
本文转载自:https://blog.csdn.net/ty_laurel/article/details/51685193 FUSE概述 FUSE(用户态文件系统)是一个实现在用户空间的文件系统框架 ...
- 算法(Algorithms)第4版 练习 1.3.29
代码实现: //1.3.29 package com.qiusongde.linkedlist; import java.util.Iterator; import java.util.NoSuchE ...
- 最近采集写的一个超简单实用的HTML解析类
1. [文件] HtmlDom.php <?php$oldSetting = libxml_use_internal_errors( true ); libxml_clear_errors(); ...
- jQuery Tab选项卡切换代码
jQuery Tab选项卡切换代码是一款简单的jquery tab选项卡切换网页特效代码样式,可以修改tab选项卡相关样式. 代码下载:http://www.huiyi8.com/sc/10863.h ...