zoukankan      html  css  js  c++  java
  • 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
    ", Max, ans/2);
    136     }
    137     return 0;
    138 }
  • 相关阅读:
    记录一个用关于mybatis对象为null的坑
    微信小程序开发初体验--教你开发小程序
    聚合数据全国天气预报api接口
    免费的无次数限制的各类API接口(2)
    外卖订单爬虫(美团,饿了么,百度外卖)
    如何快速开发出一个高质量的APP——创业谈
    调用手机话费充值API的SDK编写思路
    基于Retrotfit2.1+Material Design+ijkplayer开发的一个APP(新闻,gif 动图,视频播放)
    技巧:利用 Workflow 显示附近的免费 Wi-Fi
    MyDiary,《你的名字。》同款日记应用
  • 原文地址:https://www.cnblogs.com/Recoder/p/5947454.html
Copyright © 2011-2022 走看看