1. 程式人生 > >HDU3534 Tree(樹形dp)

HDU3534 Tree(樹形dp)

題目連結:http://acm.hdu.edu.cn/showproblem.php?pid=3534


Tree

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1144    Accepted Submission(s): 346


Problem Description In the Data structure class of HEU, the teacher asks one problem: How to find the longest path of one tree and the number of such longest path?  
Input There are several test cases. The first line of each case contains only one integer N, means there are N nodes in the tree. N-1 lines follow, each line has three integers w,v and len, indicate that there is one edge between node w and v., and the length of the edge is len.

 
Output For each test case, output the length of longest path and its number in one line.  
Sample Input
4 1 2 100 2 3 50 2 4 50 4 1 2 100 2 3 50 3 4 50  
Sample Output

  
   150 2 200 1
   
  
 
   
  題意:找出給定樹的最長路徑和最長路徑數目。 
 

思路:在深搜的時候記錄下來以當前點為根的最長路徑和個數,同時更新maxlen 和計數器cnt。

程式碼:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e4 + 5;
struct node {
    int v, w;
    node(int v, int w) {
        this->v=v;
        this->w=w;
    }
};
int d[maxn], num[maxn];
int maxlen, cnt;
vector<node> rec[maxn];
void dfs(int pre, int fa) {
    num[pre] = 1;
    for(int i = 0; i < rec[pre].size(); i++) {
        int t = rec[pre][i].v, w = rec[pre][i].w;
        if(t == fa) continue;
        dfs(t, pre);
        // 更新maxlen 和 cnt
        if(d[pre] + d[t] + w > maxlen) {  
            maxlen = d[pre] + d[t] + w;
            cnt = num[pre]*num[t];
        } else if(d[pre] + d[t] + w == maxlen) {
            cnt += num[pre]*num[t];
        }
        // 記錄更新以pre為根的最長路徑的值和個數
        if(d[t] + w > d[pre]) {          
            d[pre] = d[t] + w;
            num[pre] = num[t];
        } else if(d[t] + w == d[pre]) {
            num[pre] += num[t];
        }

    }
}
int main() {
    int n;
    while(~scanf("%d", &n)) {
        for(int i = 0; i <= n; i++) rec[i].clear();
        cnt = maxlen = 0;
        memset(d, 0, sizeof(d));
        for(int i = 0; i < n-1; i++) {
            int a, b, c;
            scanf("%d %d %d", &a, &b, &c);
            rec[a].push_back(node(b, c));
            rec[b].push_back(node(a, c));
        }
        dfs(1, -1);
        printf("%d %d\n", maxlen, cnt);
    }
    return 0;
}