hdu2196(树的直径)

链接:点击打开链接

题意:求一棵树中每个节点距离其它节点的最大距离

代码1:

#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
struct node{
    int to,cost;
};
vector<node> G[10005];
int n,dp[10005],vis[10005],dis[10005][5];
void dfs1(int s){
    int i,tmp;
    for(i=0;i<G[s].size();i++){
        tmp=G[s][i].to;
        if(G[tmp].size())
        dfs1(tmp);
        if(dis[tmp][0]+G[s][i].cost>dis[s][0]){
            dis[s][0]=dis[tmp][0]+G[s][i].cost;
            vis[s]=tmp;
        }
    }
    for(i=0;i<G[s].size();i++){
        tmp=G[s][i].to;
        if(tmp!=vis[s])
        dis[s][1]=max(dis[s][1],dis[tmp][0]+G[s][i].cost);
    }
}                                               //从下向上更新最长距离
void dfs2(int s){
    int i,tmp;
    for(i=0;i<G[s].size();i++){
        tmp=G[s][i].to;
        if(tmp==vis[s])                         //判断是否在父节点的最长路径上
        dp[tmp]=max(dp[s],dis[s][1])+G[s][i].cost;
        else
        dp[tmp]=max(dp[s],dis[s][0])+G[s][i].cost;
        dfs2(tmp);
    }
}                                               //从上向下跟新最长距离
int main(){                                     //距离当前节点最远的点无非是向下找或者向上找
    int i,j,x,y;                                //因此向下找最长距离就用一次dfs,向上找的最长
    while(scanf("%d",&n)!=EOF){                 //距离需要判断需要判断是否在当前父节点的最长路
        memset(dp,0,sizeof(dp));                //径上,如果在则向上的最长距离为父节点的次长距
        memset(dis,0,sizeof(dis));              //离加上两点的距离,否则为父节点的最长距离加上
        memset(vis,0,sizeof(vis));              //两点的距离
        for(i=1;i<=n;i++)
        G[i].clear();
        for(i=2;i<=n;i++){
            scanf("%d%d",&x,&y);
            G[x].push_back((node){i,y});        //建树
        }
        dfs1(1);
        dfs2(1);
        for(i=1;i<=n;i++)
        printf("%d\n",max(dis[i][0],dp[i]));    //比较向下的距离和向上的距离
    }
    return 0;
}

代码2:

#include <map>
#include <set>
#include <queue>
#include <string>
#include <math.h>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;
const int siz=10005;
int ans,dp[siz][2];
struct node{
    int u,v;
};
vector<node> G[siz];
void dfs(int S,int fa,int sum,int &op){
    int i,tmp;
    if(sum>ans){
        ans=sum;
        op=S;
    }
    for(i=0;i<G[S].size();i++){
        tmp=G[S][i].u;
        if(tmp==fa)
        continue;
        dfs(tmp,S,sum+G[S][i].v,op);
    }
}
void dfs_cal(int S,int fa,int op){
    int i,tmp;
    for(i=0;i<G[S].size();i++){
        tmp=G[S][i].u;
        if(tmp==fa)
        continue;
        dp[tmp][op]=dp[S][op]+G[S][i].v;
        dfs_cal(tmp,S,op);
    }
}
int main(){                                     //因为树上任意一点距离最远的点一定是
    int n,i,j,u,v;                              //树的直径的端点,因此求出直径的端点
    while(scanf("%d",&n)!=EOF){                 //再算一下距离
        for(i=1;i<=n;i++)
        G[i].clear();
        for(i=2;i<=n;i++){
            scanf("%d%d",&u,&v);
            G[u].push_back((node){i,v});
            G[i].push_back((node){u,v});
        }
        ans=0;
        dfs(1,-1,0,u);
        ans=0;
        dfs(u,-1,0,v);
        memset(dp,0,sizeof(dp));
        dfs_cal(u,-1,0);
        dfs_cal(v,-1,1);
        for(i=1;i<=n;i++)
        printf("%d\n",max(dp[i][0],dp[i][1]));
    }
    return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值