HDU 2196 Computer (树上最远距离)

题意:给你一棵树,之后让你求出这个树上每个点的距离的最大值。

思路:首先怎样求一个树上一个点到另外一个点的最远距离?其实就是一个点往父亲方向的最大值+往儿子方向的最大值,可知这些东西肯定都是单向的,因为你要么往儿子方向走你就只能往儿子方向走,不能再回去往父亲方向走,那么我们就可以设:

f[u]表示的是你往儿子方向的最大值,

g[u]表示的是你往父亲方向的最大值,

p[u]表示的是u的父亲,那么就有:

f[u] = max(f[v] + w(u,v))  // v 是 u 的儿子

g[u] = w(p[u],u) + max(g[p[u]] , w(u,v) + f[u])   // v 是 u的兄弟。

解释一下g[u]这个dp方程首先就是我们遍历u的父亲节点,最大值是怎样转移的?有两种情况1:从u的父亲哪里转移,2从u的兄弟哪里拐过来的,之后求一个最大值就好了

代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 10000 + 10;
vector<pair<int,int> >G[maxn];
int p[maxn] , f[maxn] , g[maxn];
void dfs1(int u,int fa)
{
    p[u] = fa;
    for(int i = 0 ; i < G[u].size() ; i ++)
    {
        int v = G[u][i].first , w = G[u][i].second;
        if(v == fa) continue;
        dfs1(v,u);
        f[u] = max(f[v] + w , f[u]);
    }
}
void dfs2(int u , int fa)
{
    int t = 0;
    g[u] = g[fa];
    for(auto i : G[fa])
    {
        int v = i.first , w = i.second;
        if(v == p[fa]) continue;
        if(v == u) t = w;
        else g[u] = max(g[u] , f[v] + w);
    }
    g[u] += t;
    for(auto i : G[u])
    {
        int v = i.first;
        if(v == fa) continue;
        dfs2(v,u);
    }
}
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        memset(f,0,sizeof(f));
        memset(g,0,sizeof(g));
        for(int i = 1 ; i <= n ;i ++) G[i].clear();
        int v , w;
        for(int u = 2 ; u <= n ; u++)
        {
            scanf("%d%d",&v,&w);
            G[u].push_back(make_pair(v,w));
            G[v].push_back(make_pair(u,w));
        }
        dfs1(1,0);
        dfs2(1,0);
        for(int i = 1 ; i <= n ; i++) printf("%d\n",max(f[i],g[i]));

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值