首页 > 代码库 > HDU 3534 Tree (经典树形dp)

HDU 3534 Tree (经典树形dp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3534

题意:

        给你一棵树,问你有多少对点的距离等于树的直径。

思路:

        dp[i][0]表示在i的子树中 离i最远的距离,dp[i][1]是次远距离。   cnt[i][0]则是最远的点的数量,cnt[i][1]表示次远的数量。

        up[i]表示以i向上 离i最远的距离。   up_cnt[i]表示向上最远的数量。

        写的有点麻烦,调试了2小时。。。

  1 //#pragma comment(linker, "/STACK:102400000, 102400000")  2 #include <algorithm>  3 #include <iostream>  4 #include <cstdlib>  5 #include <cstring>  6 #include <cstdio>  7 #include <vector>  8 #include <cmath>  9 #include <ctime> 10 #include <list> 11 #include <set> 12 #include <map> 13 using namespace std; 14 typedef long long LL; 15 typedef pair <int, int> P; 16 const int N = 2e5 + 5; 17 int dp[N][2]; 18 int cnt[N][2]; 19 int up[N]; 20 int cnt_up[N]; 21 int son[N][2]; 22 vector <P> G[N]; 23  24 void dfs1(int u, int p) { 25     dp[u][0] = dp[u][1] = 0; 26     son[u][0] = son[u][1] = u; 27     cnt[u][0] = cnt[u][1] = 1; 28     int tmp = 0; 29     for(int i = 0; i < G[u].size(); ++i) { 30         P temp = G[u][i]; 31         int v = temp.first; 32         if(v == p) 33             continue; 34         dfs1(v, u); 35         if(dp[v][0] + temp.second > dp[u][0]) { 36             dp[u][1] = dp[u][0]; 37             son[u][1] = son[u][0]; 38             cnt[u][1] = cnt[u][0]; 39             dp[u][0] = dp[v][0] + temp.second; 40             son[u][0] = v; 41             cnt[u][0] = cnt[v][0]; 42             tmp = cnt[v][0]; 43         } else if(dp[v][0] + temp.second == dp[u][0]) { 44             cnt[u][0] += cnt[v][0]; 45             cnt[u][1] = cnt[u][0] - tmp; 46             dp[u][1] = dp[u][0]; 47             son[u][1] = v; 48         } else if(dp[v][0] + temp.second > dp[u][1]) { 49             dp[u][1] = dp[v][0] + temp.second; 50             cnt[u][1] = cnt[v][0]; 51             son[u][1] = v; 52         } else if(dp[v][0] + temp.second == dp[u][1]) { 53             cnt[u][1] += cnt[v][0]; 54         } 55     } 56 } 57  58 void dfs2(int u, int p) { 59     for(int i = 0; i < G[u].size(); ++i) { 60         P temp = G[u][i]; 61         int v = temp.first; 62         if(v == p) 63             continue; 64         if(dp[u][0] == temp.second + dp[v][0]) { 65             //up[v] = max(up[u], dp[u][0]) + temp.second; 66             if(dp[u][1] == 0) { 67                 cnt_up[v] = cnt_up[u]; 68                 up[v] = up[u] + temp.second; 69                 dfs2(v, u); 70                 continue; 71             } 72             if(up[u] > dp[u][1]) { 73                 up[v] = up[u] + temp.second; 74                 cnt_up[v] = cnt_up[u]; 75             } else if(dp[u][1] > up[u]) { 76                 up[v] = dp[u][1] + temp.second; 77                 if(dp[u][1] == dp[u][0]) 78                     cnt_up[v] = cnt[u][0] - cnt[v][0]; 79                 else 80                     cnt_up[v] = cnt[u][1]; 81             } else { 82                 if(dp[u][1] == dp[u][0]) 83                     cnt_up[v] = cnt[u][0] - cnt[v][0]; 84                 else 85                     cnt_up[v] = cnt[u][1]; 86                 cnt_up[v] += cnt_up[u]; 87                 up[v] = dp[u][1] + temp.second; 88             } 89         } else { 90             //up[v] = max(up[u], dp[u][1]) + temp.second; 91             if(up[u] > dp[u][0]) { 92                 up[v] = up[u] + temp.second; 93                 cnt_up[v] = cnt_up[u]; 94             } else if(dp[u][0] > up[u]) { 95                 up[v] = dp[u][0] + temp.second; 96                 cnt_up[v] = cnt[u][0]; 97             } else { 98                 cnt_up[v] = cnt_up[u] + cnt[u][0]; 99                 up[v] = dp[u][0] + temp.second;100             }101         }102         dfs2(v, u);103     }104 }105 106 int main()107 {108     int n, u, v, c;109     while(~scanf("%d", &n)) {110         for(int i = 1; i <= n; ++i) {111             G[i].clear();112         }113         for(int i = 1; i < n; ++i) {114             scanf("%d %d %d", &u, &v, &c);115             G[u].push_back(make_pair(v, c));116             G[v].push_back(make_pair(u, c));117         }118         dfs1(1, -1);119         cnt_up[1] = 1;120         dfs2(1, -1);121         int Max = 0;122         for(int i = 1; i <= n; ++i) {123             //cout << dp[i][0] << "  -  " << up[i] << endl;124             Max = max(Max, max(dp[i][0], up[i]));125         }126         LL ans = 0;127         for(int i = 1; i <= n; ++i) {128             if(Max == dp[i][0]) {129                 ans += (LL)cnt[i][0];130             }131             if(Max == up[i]) {132                 ans += (LL)cnt_up[i];133             }134         }135         printf("%d %lld\n", Max, ans/2);136     }137     return 0;138 }

 

HDU 3534 Tree (经典树形dp)