zoukankan      html  css  js  c++  java
  • HDU2196computer


    就是求每个点为起始点的最长链的长度。

    写一下各个数组的意思吧。

    f[i][0]为点i向下走最长的距离;f[i][1]为点i向下走第二长的距离;

    xia[i][0]为点i向下走最长距离所要走的儿子节点;

    xia[i][1]为点i向下走第二长长距离所要走的儿子节点;

    f[i][2]为点i向上走的最大距离;

    显而易见求向下的DP递推就好了。

    求向上的DP

     注意:两个DP都是从根节点往下更新。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define maxn 10010 << 1
    using namespace std;
    int head[maxn],tot,n,u,v,val,len[maxn],f[maxn][3];
    int xia[maxn][2],l[maxn];
    struct st{
        int v,val,next;
        st clear(){
            v = val = next = 0;
        }
    }s[maxn];
    
    void add(int u,int v,int val)
    {
        tot++;
        s[tot].v = v;
        s[tot].val = val;
        s[tot].next = head[u];
        head[u] = tot;
    }
    
    void dfs(int fa,int now)
    {
        for(int i=head[now];i;i=s[i].next)
            if(s[i].v != fa)
            {
                l[s[i].v] = s[i].val;
                dfs(now,s[i].v);
                len[now] = max(len[s[i].v] + s[i].val,len[now]);
                int k = len[s[i].v] + s[i].val;
                if(f[now][1] < k)
                {
                    f[now][1] = k;
                    xia[now][1] = s[i].v;
                }
                if(f[now][1] > f[now][0]) 
                {
                    swap(xia[now][0],xia[now][1]);
                    swap(f[now][1],f[now][0]);
                }
            }
    }
    
    void find(int fa,int now)
    {
        f[now][2] = max(f[fa][2] , now == xia[fa][0] ? f[fa][1] : f[fa][0]) + l[now];
        for(int i=head[now];i;i=s[i].next)
            if(s[i].v != fa)
                find(now,s[i].v);
    }
    
    int main(){
        
        while(scanf("%d",&n) != EOF)
        {
            
            for(int i=1;i<=2 * n;i++)
            {
                head[i] = f[i][0] = f[i][1] = f[i][2] = len[i] = l[i] = xia[i][0] = xia[i][1] = 0;
                s[i].clear();
            }
            tot = 0; 
            for(int i=2;i<=n;i++)
            {
                scanf("%d%d",&v,&val);
                add(i,v,val);
                add(v,i,val);
            }
            
            dfs(0,1);
            
            find(0,1);
            
            for(int i=1;i<=n;i++) printf("%d
    ",max(f[i][0],f[i][2]));
            
        }
    }
  • 相关阅读:
    c++中关于用stringstream进行的类型转化
    c++中字符串的反转
    搬家
    初次见面,请多关照。
    CCPC2019吉林省赛&&东北地区赛游记
    VS Code下搭建简单的Haskell开发环境
    从零开始的KMP&&AC自动机
    从零开始的LCA(最近公共祖先)
    LuoguP2123 皇后游戏
    LuoguP1080 国王游戏
  • 原文地址:https://www.cnblogs.com/kczno1fans/p/7755063.html
Copyright © 2011-2022 走看看