hdu--2196--树上某点到其余结点的最远距离

这题 很多人都是用树形dp进行2次dfs做的...

我看了他们的解题报告 并没有完全搞懂=-= 我太白痴了 伤..

这边 我的解法 利用了一个很重要的性质---树的直径--树上任意两点间的最远距离

而同时 将这个直径上的两点x , y确定后 那么 整个树上结点的dist[ i ]也就可以确定了

max( dist[i][x] , dist[i][y] ) 要么是到x的距离 要么是到y的距离

至于 怎么找出这个直径呢?

这也是个要记住的地方 我们可以任意确定一个根结点开始bfs 得到距离它最远的结点编号 那么这个结点就是 树中直径的某一端点

然后再bfs这个得到的端点 可以得到直径的另一端点 最后Bfs这个端点  同时在这对于直径端点的bfs中  分别用不同数组记录下距离

最后用max输出

 1 #include <iostream>
 2 #include <cstring>
 3 #include <queue>
 4 #include <algorithm>
 5 using namespace std;
 6
 7 int cnt;
 8 const int size = 10010;
 9 struct data
10 {
11     int to;
12     int val;
13     int next;
14 }node[size*2];
15 int head[size];
16 int dist1[size];
17 int dist2[size];
18 bool vis[size];
19
20 void init( )
21 {
22     memset( head , -1 , sizeof(head) );
23     memset( dist1 , 0 , sizeof(dist1) );
24     memset( dist2 , 0 , sizeof(dist2) );
25 }
26
27 void addEdge( int from , int to , int dist )
28 {
29     node[cnt].to = to;
30     node[cnt].val = dist;
31     node[cnt].next = head[from];
32     head[from] = cnt ++;
33 }
34
35 int bfs( int num , int* dist )
36 {
37     int ans , now , len;
38     len = -1;
39     memset( vis , false , sizeof(vis) );
40     queue<int>q;
41     q.push(num);
42     vis[num] = 1;
43     while( !q.empty() )
44     {
45         now = q.front();
46         q.pop();
47         if( dist[now] > len )
48         {
49             len = dist[now];
50             ans = now;
51         }
52         for( int i = head[now] ; ~i ; i = node[i].next )
53         {
54             int to = node[i].to;
55             int val = node[i].val;
56             if( !vis[to] )
57             {
58                 vis[to] = true;
59                 q.push(to);
60                 dist[to] = dist[now] + val;
61             }
62         }
63     }
64     return ans;
65 }
66
67 int main()
68 {
69     cin.sync_with_stdio(false);
70     int n , x , y , point;
71     while( cin >> n )
72     {
73         cnt = 0;
74         init( );
75         for( int i = 2 ; i<=n ; i++ )
76         {
77             cin >> x >> y;
78             addEdge( i , x , y );
79             addEdge( x , i , y );
80         }
81         point = bfs( 1 , dist1 );
82         memset( dist1 , 0 , sizeof(dist1) );
83         point = bfs( point , dist1 );
84         point = bfs( point , dist2 );
85         for( int i = 1 ; i<=n ; i++ )
86         {
87             cout << max( dist1[i] , dist2[i] ) << endl;
88         }
89     }
90     return 0;
91 }

today:

  人们说

  当遇上你的挚爱时

  时间会暂停

  那是真的

  但人们没有告诉你

  当时针再度恢复转动

  它会无比飞快

  让人无法追上

   

时间: 2024-10-11 18:05:05

hdu--2196--树上某点到其余结点的最远距离的相关文章

HDU 4123(树上任意点到其他点的最远距离,rmq

题目:求出一棵树上任意一点能到的最远距离,然后若干询问,问区间内最大最小距离只差小于q的区间最长有多长. 思路:最远距离通过两次dfs树形dp求得,询问需要先用st表处理一下,然后线性扫.基本是参考kuangbin的. ps:可能是我写挫了..用vector做邻接表是1996ms过了一次,然后就是无限tle....不得不改成手写链表才搞到1500ms...vector感觉不能随便用了啊...... http://www.cnblogs.com/kuangbin/archive/2013/11/0

HDU 2196 Computer (树上最长路)【树形DP】

<题目链接> 题目大意: 输出树上每个点到其它点的最大距离. 解题分析: 下面的做法是将树看成有向图的做法,计算最长路需要考虑几种情况. dp[i][0] : 表示以i为根的子树中的结点与i的最大距离 dp[i][1] : 表示以i为根的子树中的结点与u的次大距离 dp[i][2] : 表示i往父亲节点方向走的最大距离 第一就是点 i 在以点 i 为根的子树中的最长距离,这个可以直接在点 i 的子树中求得: 第二就是点 i 朝父亲节点方向的最长距离,这个距离分为三种: 1) 点 i 在以 fa

hdu 2196(树的最长链)

题意:输出从一颗树中所有结点出发可以走的最长的路. 思路:先找到树上最长链然后判断两个端点中到每个结点远的距离就是答案. 代码如下: 1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <algorithm> 5 #include <vector> 6 #include <queue> 7 #include <set> 8

HDU 2196 树状dp 求树中节点之间的最长距离

Computer Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3749    Accepted Submission(s): 1892 Problem Description A school bought the first computer some time ago(so this computer's id is 1). Du

HDU 2196 Computer 经典树形DP

一开始看错题了,后来发现原来是在一颗带权的树上面求出距离每一个点的最长距离,做两次dfs就好,具体的看注释? #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #incl

HDU 2196 Computer 二次扫描与换根DP

题意:给定一棵树,求树上所有点到其最远点的距离. 数据范围: 1 <= N <= 100000 ------------------------------------------我是分割线------------------------------------------ 题解:对于每个节点u来说,其可能到达的最长距离为max{其子树内的最长距离,其父节点不经过u的子树内的最长距离}.于是,我们便可以在第一遍dfs中预处理节点x到其子树内的最长距离,顺带求一下次长距离,方便转移. // f[

Computer HDU - 2196(树形dp)

题目要求:求树上每个点能到达的最远距离 dp[u][0]:u的子树下u的最远距离是多少 dp[u][1]:u的子树次远距离是多少 dp[u][2]:u的父亲能走的最远距离是多少 dp[0] [1]dfs处理即可 如果vi不是u最长距离经过的节点,f[vi][1] = dist(vi,u)+max(f[u][0], f[u][1]) 如果vi是u最长距离经过的节点,那么不能选择f[u][0],因为这保存的就是最长距离,要选择u次大距离 #include<bits/stdc++.h> #defin

(算法)二叉树两个结点的最远距离

题目: 求二叉树两个结点的最远距离. 二叉树定义如下: class TreeNode{ public: int val; TreeNode* left; TreeNode* right; TreeNode(int x):val(x),left(NULL),right(NULL){} }; 思路: 遍历每个节点,找出以当前节点为根的最长路径,然后找出所有最长路径中的最大值. 代码: 代码1: class Node{ public: int val; Node* left; Node* right;

HDU 2196 求树上所有点能到达的最远距离

其实我不是想做这道题的...只是今天考试考了一道类似的题...然后我挂了... 但是乱搞一下还是有80分....可惜没想到正解啊! 所以今天的考试题是: 巡访 (path.pas/c/cpp) Chanxer终于当上了“中华农民联盟”的盟主,他举目四望,决定四处走走,巡视自己的农土. “中华农民联盟”的成员有个村庄,在“村村通”计划中,村庄们被条道路联通了起来,Chanxer计划从某个村庄出发,访问所有的村庄. 可是Chanxer出行有一个特殊的要求,那就是必须以农车代步,现在我们知道哪些村庄配