HDU - 2196
Posted xFANx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU - 2196相关的知识,希望对你有一定的参考价值。
求从树上每一点出发能得到的最长路。
对于一个结点node,从它出发的最长路要么是它向子树走能得到的最大值,要么是先走向parent,再加上parent的不经过node的最长路的值。此时parent有可能走向它的父亲,或者走向node的兄弟结点。所以每个点我们要记录向子树走的最长路dp[node][1]和次长路dp[node][2],还要记录经过其父亲结点的最长路dp[node][3]。
前两个可以在一次dfs中处理出,最后再用一次dfs求出经过父亲的最长路
1 #include <vector> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 7 const int maxn = 1e4 + 10; 8 int N; 9 int dp[maxn][4]; 10 vector<int> tree[maxn]; 11 12 void dfs1(int par) { 13 int fir = 0, sec = 0; 14 for (int i = 0; i < tree[par].size(); i++) { 15 int v = tree[par][i]; 16 dfs1(v); 17 int tmp = dp[v][1] + dp[v][0]; 18 if (tmp >= fir) { 19 sec = fir; fir = tmp; 20 } else if (tmp > sec) { 21 sec = tmp; 22 } 23 } 24 dp[par][1] = fir; dp[par][2] = sec; 25 } 26 27 void dfs2(int par) { 28 for (int i = 0; i < tree[par].size(); i++) { 29 int v = tree[par][i]; 30 dp[v][3] = dp[v][0] + max(dp[par][3], 31 (dp[v][0] + dp[v][1] == dp[par][1] ? dp[par][2] : dp[par][1])); 32 dfs2(v); 33 } 34 } 35 36 int main() { 37 while (~scanf("%d", &N)) { 38 memset(dp, 0, sizeof(dp)); 39 for (int i = 0; i <= N; i++) tree[i].clear(); 40 for (int i = 2; i <= N; i++) { 41 int u; 42 scanf("%d%d", &u, &dp[i][0]); 43 tree[u].push_back(i); 44 } 45 dfs1(1); 46 dfs2(1); 47 for (int i = 1; i <= N; i++) printf("%d\n", max(dp[i][1],dp[i][3])); 48 } 49 return 0; 50 }
以上是关于HDU - 2196的主要内容,如果未能解决你的问题,请参考以下文章