当前位置: 首页 > news >正文

[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]);$

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

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

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn=1e5+2;
 5 int head[maxn],tot,d[maxn][3],longest[maxn];
 6 struct edge{
 7     int to;
 8     int nxt;
 9     int w;
10 }e[maxn<<1];
11 void add_edge(int u,int v,int w){
12     e[tot].to=v;
13     e[tot].w=w;
14     e[tot].nxt=head[u];
15     head[u]=tot++;
16 }
17 
18 int dfs1(int u,int fa){//返回子树最大距离 
19     for(int i=head[u];i!=-1;i=e[i].nxt){
20         int v=e[i].to;
21         if(v==fa) continue;
22         int tmp=dfs1(v,u);
23         if(d[u][0]<tmp+e[i].w){
24             longest[u]=v;
25             d[u][1]=d[u][0];
26             d[u][0]=tmp+e[i].w;
27         }else if(d[u][1]<tmp+e[i].w){//求次大距离必须加else if 
28             d[u][1]=tmp+e[i].w;
29         }
30     }
31     return d[u][0];
32 }
33 
34 void dfs2(int u,int fa){
35     for(int i=head[u];i!=-1;i=e[i].nxt){
36         int v=e[i].to;
37         if(v==fa) continue;
38         if(v==longest[u]) d[v][2]=max(d[u][1],d[u][2])+e[i].w;
39         else d[v][2]=max(d[u][0],d[u][2])+e[i].w;
40         dfs2(v,u);
41     }
42 } 
43 
44 
45 int main(){
46     int n;
47     ios::sync_with_stdio(0);
48     cin.tie(0);
49     cout.tie(0);
50     while(cin>>n){
51         tot=0;
52         memset(d,0,sizeof d);
53         memset(head,-1,sizeof head);
54         memset(longest,0,sizeof longest);
55         int a,b;
56         for(int i=2;i<=n;i++){
57             cin>>a>>b;
58             add_edge(i,a,b);
59             add_edge(a,i,b);
60         }
61         dfs1(1,-1);
62         dfs2(1,-1);
63         for(int i=1;i<=n;i++){
64             cout<<max(d[i][0],d[i][2])<<"\n";
65         }
66     }
67     return 0;
68 }

 最优写法:

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

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn=1e5+2;
 5 int head[maxn],tot,d[maxn][3];
 6 struct edge{
 7     int to;
 8     int nxt;
 9     int w;
10 }e[maxn<<1];
11 void add_edge(int u,int v,int w){
12     e[tot].to=v;
13     e[tot].w=w;
14     e[tot].nxt=head[u];
15     head[u]=tot++;
16 }
17 
18 void dfs1(int u,int fa){//返回子树最大距离 
19     for(int i=head[u];i!=-1;i=e[i].nxt){
20         int v=e[i].to;
21         if(v==fa) continue;
22         dfs1(v,u);
23         int tmp=d[v][0]+e[i].w;
24         if(d[u][0]<=tmp){
25             d[u][1]=d[u][0];
26             d[u][0]=tmp;
27         }else if(d[u][1]<tmp){//求次大距离必须加else if 
28             d[u][1]=tmp;
29         }
30     }
31 }
32 
33 void dfs2(int u,int fa){
34     for(int i=head[u];i!=-1;i=e[i].nxt){
35         int v=e[i].to;
36         if(v==fa) continue;
37         if(d[u][0]==d[v][0]+e[i].w) d[v][2]=max(d[u][1],d[u][2])+e[i].w;
38         else d[v][2]=max(d[u][0],d[u][2])+e[i].w;
39         dfs2(v,u);
40     }
41 } 
42 
43 
44 int main(){
45     int n;
46     ios::sync_with_stdio(0);
47     cin.tie(0);
48     cout.tie(0);
49     while(cin>>n){
50         tot=0;
51         memset(d,0,sizeof d);
52         memset(head,-1,sizeof head);
53         int a,b;
54         for(int i=2;i<=n;i++){
55             cin>>a>>b;
56             add_edge(i,a,b);
57             add_edge(a,i,b);
58         }
59         dfs1(1,-1);
60         dfs2(1,-1);
61         for(int i=1;i<=n;i++){
62             cout<<max(d[i][0],d[i][2])<<"\n";
63         }
64     }
65     return 0;
66 }

 

转载于:https://www.cnblogs.com/elpsycongroo/p/7418815.html

相关文章:

  • Android开发艺术探索
  • Java-网络编程 socket
  • jq 误解之点击一次 请求发送了两次
  • 信噪比——信号加噪相关的知识
  • 网络流24题 负载平衡(DCOJ8013)
  • 对于maven创建spark项目的pom.xml配置文件(图文详解)
  • mongoDB (mongoose、增删改查、聚合、索引、连接、备份与恢复、监控等等)
  • bzoj3675 序列分割
  • 恋愛SLG-「メイド服セット」ゲットチャレンジ!
  • 1、python全栈之路-数据类型
  • 分布式数据库架构及企业实践--基于Mycat中间件pdf
  • pycharm gerrit
  • python即时标记
  • try catch 小结 , node的回调callback里不能捕获异常 , 不能被v8优化(现在能了),...
  • 实现多线程的另一种方式-Callable
  • JS中 map, filter, some, every, forEach, for in, for of 用法总结
  • 【刷算法】从上往下打印二叉树
  • bootstrap创建登录注册页面
  • canvas绘制圆角头像
  • Java,console输出实时的转向GUI textbox
  • JavaScript设计模式之工厂模式
  • mongo索引构建
  • Python socket服务器端、客户端传送信息
  • 创建一个Struts2项目maven 方式
  • 构建工具 - 收藏集 - 掘金
  • 前端存储 - localStorage
  • 前言-如何学习区块链
  • 深入浅出webpack学习(1)--核心概念
  • 吴恩达Deep Learning课程练习题参考答案——R语言版
  • SAP CRM里Lead通过工作流自动创建Opportunity的原理讲解 ...
  • 京东物流联手山西图灵打造智能供应链,让阅读更有趣 ...
  • ​520就是要宠粉,你的心头书我买单
  • ​ubuntu下安装kvm虚拟机
  • ## 临床数据 两两比较 加显著性boxplot加显著性
  • #预处理和函数的对比以及条件编译
  • (175)FPGA门控时钟技术
  • (26)4.7 字符函数和字符串函数
  • (LeetCode) T14. Longest Common Prefix
  • (二)Eureka服务搭建,服务注册,服务发现
  • (附源码)springboot“微印象”在线打印预约系统 毕业设计 061642
  • (机器学习的矩阵)(向量、矩阵与多元线性回归)
  • (一)RocketMQ初步认识
  • (一)UDP基本编程步骤
  • (转载)Linux网络编程入门
  • .bat批处理(五):遍历指定目录下资源文件并更新
  • .mysql secret在哪_MYSQL基本操作(上)
  • .net/c# memcached 获取所有缓存键(keys)
  • [ 云计算 | Azure 实践 ] 在 Azure 门户中创建 VM 虚拟机并进行验证
  • [APIO2015]巴厘岛的雕塑
  • [APUE]进程关系(下)
  • [bbk5179]第66集 第7章 - 数据库的维护 03
  • [BUG]Datax写入数据到psql报不能序列化特殊字符
  • [C#]OpenCvSharp使用帧差法或者三帧差法检测移动物体
  • [C]整形提升(转载)
  • [EULAR文摘] 脊柱放射学持续进展是否显著影响关节功能