• HDU2196


    题目大意

    给定一颗n个结点的树,编号为1~n,要求你求出每个结点能到达的最长路径

    题解

    用动态规划解决的~~~~把1 当成树根,这样就转换成有根树了。我们可以发现,对于每个结点的最长路,要么是从子树得到要么是从父亲得到我们用数组f,g,h分别记录从当前结点到子树能够获得的最大值和第二大值以及从当前结点到祖先能够获得的最大值。我们先进行一次dfs,把f和g值求出来,然后再进行一次dfs求出h的值来,对于h值,得分两种情况,对于当前结点s的h值,如果它的父亲得最长路径没有经过结点s,假设父亲结点为v,那么h的值为dis(s,v)+max(f[v],h[v]),否则的话h的值为dis(s,v)+max(g[v],h[v])

    代码:

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    using namespace std;
    #define  MAXN 10005
    vector<int>ivec[MAXN],value[MAXN];
    int  f[MAXN],g[MAXN],h[MAXN];
    int son[MAXN];
    int dfs1(int root)
    {
        if(f[root]) return f[root];
        if(ivec[root].empty()) return 0;
        int len=ivec[root].size();
        for(int i=0; i<len; i++)
            if(dfs1(ivec[root][i])+value[root][i]>f[root])
            {
                f[root]=f[ivec[root][i]]+value[root][i];
                son[root]=ivec[root][i];
            }
        for(int i=0; i<len; i++)
            if(ivec[root][i]!=son[root]&&f[ivec[root][i]]+value[root][i]>g[root])
                g[root]=f[ivec[root][i]]+value[root][i];
        return f[root];
    }
    void dfs2(int root)
    {
        if(ivec[root].empty()) return;
        int len=ivec[root].size();
        for(int i=0; i<len; i++)
        {
            if(ivec[root][i]!=son[root])
                h[ivec[root][i]]=value[root][i]+max(f[root],h[root]);
           else
                h[ivec[root][i]]=max(g[root],h[root])+value[root][i];
            dfs2(ivec[root][i]);
        }
    }
    int main()
    {
        int n;
        while(scanf("%d",&n)!=EOF)
        {
            for(int i=1; i<=n; i++)
            {
                ivec[i].clear();
                value[i].clear();
            }
            for(int i=2; i<=n; i++)
            {
                int a,b;
                scanf("%d%d",&a,&b);
                ivec[a].push_back(i);
                value[a].push_back(b);
            }
            memset(f,0,sizeof(f));
            memset(g,0,sizeof(g));
            memset(h,0,sizeof(h));
            f[1]=dfs1(1);
            dfs2(1);
            for(int i=1;i<=n;i++)
            printf("%d
    ",max(f[i],h[i]));
        }
        return 0;
    }
  • 相关阅读:
    php 数组
    条件语句if else ,switch ,while ,do.while
    if..else 判断中的 Boolean()转换
    wampserver 集成环境
    sublime text 安装及使用
    vue tab切换
    SVG 基础
    gitosis管理员的密钥丢失解决办法
    源码安装MySQL
    Xshell远程登录
  • 原文地址:https://www.cnblogs.com/zjbztianya/p/3417295.html
Copyright © 2020-2023  润新知