zoukankan      html  css  js  c++  java
  • HDU 2196Computer(树形DP)

    给你一颗边带权值的树,求树上的每一点距离其最远的一个点的距离

    比较典型的题了,主要方法是进行两次DFS,第一次DFS求出每一个点距离它的子树的最远距离和次远距离,然后第二次DFS从父节点传过来另一侧的树上的距离它的最远距离进行一次比较便可得出任意点的最远距离了

    之所以需要记录最远和次远是为了辨别父节点的最远距离是否是根据自己得来,如果是的话应该选择父节点的次远距离,保证结果的准确性

     1 //#pragma comment(linker,"/STACK:102400000,102400000")
     2 #include <map>
     3 #include <set>
     4 #include <stack>
     5 #include <queue>
     6 #include <cmath>
     7 #include <ctime>
     8 #include <vector>
     9 #include <cstdio>
    10 #include <cctype>
    11 #include <cstring>
    12 #include <cstdlib>
    13 #include <iostream>
    14 #include <algorithm>
    15 using namespace std;
    16 #define INF 1e8
    17 #define inf (-((LL)1<<40))
    18 #define lson k<<1, L, mid
    19 #define rson k<<1|1, mid+1, R
    20 #define mem0(a) memset(a,0,sizeof(a))
    21 #define mem1(a) memset(a,-1,sizeof(a))
    22 #define mem(a, b) memset(a, b, sizeof(a))
    23 #define FOPENIN(IN) freopen(IN, "r", stdin)
    24 #define FOPENOUT(OUT) freopen(OUT, "w", stdout)
    25 template<class T> T CMP_MIN(T a, T b) { return a < b; }
    26 template<class T> T CMP_MAX(T a, T b) { return a > b; }
    27 template<class T> T MAX(T a, T b) { return a > b ? a : b; }
    28 template<class T> T MIN(T a, T b) { return a < b ? a : b; }
    29 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
    30 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b;    }
    31 
    32 //typedef __int64 LL;
    33 //typedef long long LL;
    34 const int MAXN = 10005;
    35 const int MAXM = 20005;
    36 const double eps = 1e-13;
    37 //const LL MOD = 1000000007;
    38 
    39 int N;
    40 int head[MAXN], next[MAXM], tot;
    41 int  u[MAXM], v[MAXM], w[MAXM];
    42 int fir[MAXN], sec[MAXN], ans[MAXN];
    43 
    44 void addEdge(int U, int V, int W)
    45 {
    46     u[tot] = U;
    47     v[tot] = V;
    48     w[tot] = W;
    49     next[tot] = head[U];
    50     head[U] = tot;
    51     tot ++;
    52 }
    53 
    54 int dfs1(int x, int fa)
    55 {
    56     fir[x] = sec[x] = 0;
    57     for(int e = head[x]; e != -1; e = next[e]) if(v[e] != fa)
    58     {
    59         int dis = dfs1(v[e], x) + w[e];
    60         if(dis >= fir[x]) { sec[x] = fir[x]; fir[x] = dis; }
    61         else if(dis > sec[x]) sec[x] = dis;
    62     }
    63     return fir[x];
    64 }
    65 
    66 void dfs2(int x, int fa, int dis)
    67 {
    68     ans[x] = MAX(fir[x], dis);
    69     for(int e = head[x]; e != -1; e = next[e]) if(v[e] != fa)
    70     {
    71         int y = v[e];
    72         if(fir[y] + w[e] == fir[x])
    73             dfs2(y, x, MAX( dis, sec[x]) + w[e] );
    74         else
    75             dfs2(y, x, MAX( dis, fir[x]) + w[e] );
    76     }
    77 }
    78 
    79 int main()
    80 {
    81 
    82     while(~scanf("%d", &N))
    83     {
    84         tot = 0;
    85         mem1(head);
    86         int V, W;
    87         for(int i = 2; i <= N; i ++)
    88         {
    89             scanf("%d %d", &V, &W);
    90             addEdge(i, V, W);
    91             addEdge(V, i, W);
    92         }
    93         dfs1(1, 1);
    94         dfs2(1, 1, 0);
    95         for(int i = 1; i <= N; i ++ )
    96             printf("%d
    ", ans[i]);
    97     }
    98     return 0;
    99 }
  • 相关阅读:
    1044 拦截导弹
    3060 抓住那头奶牛 USACO
    2727:仙岛求药(广搜)
    4906 删数问题(另一种贪心思路)
    1004 四子连棋
    1005 生日礼物
    1031 质数环
    1008 选数
    1073 家族
    2801 LOL-盖伦的蹲草计划
  • 原文地址:https://www.cnblogs.com/gj-Acit/p/3888317.html
Copyright © 2011-2022 走看看