Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4990 Accepted Submission(s): 2509
题意:以1为根,建立一棵树,每个节点之间的长度为len,然后求每个节点到叶子的最远距离;
分析:求i节点,两种可能,一种是从i的子树得到最远距离,第二种是从父节点得到最远距离,所以两次dfs,第一次统计所有节点从子树到叶子的最远距离和次远距离,第一次看这道题,不明白次远距离有什么用,看到第二次dfs就明白了,第二次就要判断i是从子树还是父节点过来的,此时已经求出了子树方向的所有最长距离,最要知道父节点方向最长距离就ok了,比较一下嘛,然后父节点的最远距离有两种可能,一种是经过 i 而来的,所以求 i 父节点方向的最远距离就是 i 父节点的次最远距离了,第二种是不经过 i 而来的,所以 i 父节点方向的最远距离就是他
1 #include <iostream> 2 #include <algorithm> 3 #include <cstring> 4 #include <cstdio> 5 using namespace std; 6 const int Max = 10000 + 10; 7 struct Node 8 { 9 int to,next,len; 10 }; 11 Node edge[2 * Max]; 12 int head[Max], tol; 13 int maxn[Max],maxnId[Max]; //最远距离和最远距离对应的序号 14 int smaxn[Max],smaxnId[Max]; //次远距离和次远距离对应的序号 15 void add_edge(int a, int b, int len) 16 { 17 edge[tol].to = b; 18 edge[tol].next = head[a]; 19 edge[tol].len = len; 20 head[a] = tol++; 21 } 22 void dfs1(int u, int p) 23 { 24 maxn[u] = smaxn[u] = 0; 25 for(int i = head[u]; i != -1; i = edge[i].next) 26 { 27 int v = edge[i].to; 28 if(v == p) //如果是父节点跳过 29 continue; 30 dfs1(v, u); 31 if(smaxn[u] < maxn[v] + edge[i].len) //如果子节点的最远距离大于次远距离,就更新次远距离;先更新次远距离,由次远距离和最远距离比较更新最远距离 32 { 33 smaxn[u] = maxn[v] + edge[i].len; 34 smaxnId[u] = v; 35 if(smaxn[u] > maxn[u]) 36 { 37 swap(smaxn[u], maxn[u]); 38 swap(smaxnId[u], maxnId[u]); 39 } 40 } 41 } 42 } 43 void dfs2(int u, int p) 44 { 45 for(int i = head[u]; i != -1; i = edge[i].next) 46 { 47 int v = edge[i].to; 48 if(v == p) 49 continue; 50 if(v == maxnId[u]) //如果父节点方向最远距离经过这个子节点 51 { 52 if(smaxn[u] + edge[i].len > smaxn[v]) //选择次远距离,因为最远距离经过v点 53 { 54 smaxn[v] = smaxn[u] + edge[i].len; 55 smaxnId[v] = u; 56 if(maxn[v] < smaxn[v]) 57 { 58 swap(maxn[v], smaxn[v]); 59 swap(maxnId[v], smaxnId[v]); 60 } 61 } 62 } 63 else 64 { 65 if(maxn[u] + edge[i].len > smaxn[v]) 66 { 67 smaxn[v] = maxn[u] + edge[i].len; 68 smaxnId[v] = u; 69 if(maxn[v] < smaxn[v]) 70 { 71 swap(maxn[v], smaxn[v]); 72 swap(maxnId[v], smaxnId[v]); 73 } 74 } 75 } 76 dfs2(v, u); 77 } 78 } 79 int main() 80 { 81 int n,v,len; 82 while(scanf("%d", &n) != EOF) 83 { 84 tol = 0; 85 memset(head, -1, sizeof(head)); 86 for(int i = 2; i <= n; i++) 87 { 88 scanf("%d%d", &v, &len); 89 add_edge(i, v, len); 90 add_edge(v, i, len); 91 } 92 dfs1(1, -1); //向下 93 dfs2(1, -1); 94 for(int i = 1; i <= n; i++) 95 printf("%d\n", maxn[i]); 96 } 97 return 0; 98 }