码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 2196(树形dp

时间:2015-07-29 06:12:34      阅读:119      评论:0      收藏:0      [点我收藏+]

标签:

题目:求出一棵树上的所有点到其他点的最长距离。

思路:取一个根节点进行dfs,先求出每个节点到子节点的最长路和次长路(也就是与最长路不同的最长的路,有可能与最长路长度相等),并记录最长路和次长路通过的相邻节点的标号。然后进行第二次dfs,考虑最长路是通过父节点的情况,如果该节点v在父节点的最长路上,那么需要取次长路,否则就取最长路。

第二次dfs的时候最长路的通过节点还是要更新,因为若某个父节点的最长路是朝祖先走的,那么其子节点的最长路一定朝祖先走,且与v是否在父节点向下的最长路上无关。

技术分享
#include<iostream>
#include<map>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<queue>
#include<stack>
#include<functional>
#include<set>
#include<cmath>
#define pb push_back
#define fs first
#define se second
#define sq(x) (x)*(x)
#define eps 0.0000000001
using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;
const int maxv=1e4+300;
int N;
vector<P> G[maxv];
int maxd[maxv],maxdn[maxv],smaxd[maxv],smaxdn[maxv];
void dfs1(int u,int f){
    maxd[u]=smaxd[u]=0;
    for(int i=0;i<G[u].size();i++){
        int v=G[u][i].fs;
        int len=G[u][i].se;
        if(v==f) continue;
        dfs1(v,u);
        if(len+maxd[v]>smaxd[u]){
            smaxd[u]=len+maxd[v];
            smaxdn[u]=v;
        }
        if(smaxd[u]>maxd[u]){
            swap(smaxd[u],maxd[u]);
            swap(smaxdn[u],maxdn[u]);
        }
    }
}
void dfs2(int u,int f){
    for(int i=0;i<G[u].size();i++){
        int v=G[u][i].fs;
        int len=G[u][i].se;
        if(v==f) continue;
        if(maxdn[u]==v){
            if(smaxd[u]+len>smaxd[v]){
                smaxd[v]=smaxd[u]+len;
                smaxdn[v]=u;
            }
            if(smaxd[v]>maxd[v]){
                swap(maxd[v],smaxd[v]);
                swap(maxdn[v],smaxdn[v]);
            }
        }else{
            if(maxd[u]+len>smaxd[v]){
                smaxd[v]=maxd[u]+len;
                smaxdn[v]=u;
            }
            if(smaxd[v]>maxd[v]){
                swap(maxd[v],smaxd[v]);
                swap(maxdn[v],smaxdn[v]);
            }
        }
        dfs2(v,u);
    }
}
int main(){
    /////freopen("/home/files/CppFiles/in","r",stdin);
    /*    std::ios::sync_with_stdio(false);
        std::cin.tie(0);*/
    while(cin>>N){
        for(int i=1;i<=N;i++) G[i].clear();
        for(int i=2;i<=N;i++){
            int a,b;
            scanf("%d%d",&a,&b);
            G[i].pb(P(a,b));
            G[a].pb(P(i,b));
        }
        dfs1(1,-1);
        dfs2(1,-1);
        for(int i=1;i<=N;i++){
            printf("%d\n",maxd[i]);
        }
    }
    return 0;
}
View Code

 

HDU 2196(树形dp

标签:

原文地址:http://www.cnblogs.com/Cw-trip/p/4684812.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!