zoukankan      html  css  js  c++  java
  • Computer

    Computer (树形dp)

    给你一棵树,问你每个点能到达的最远距离。N<=10000。

    这是道树形dp入门题(流下伤心的泪水)首先一个结点,它能到的最远点要么在子树内,要么在子树外。我们根据这个来搞dp。(dp[u][0])表示在u的子树内,u能到达的最远距离。(dp[u][1])则表示子树内的次远距离。(dp[u][2])表示u经过它的父亲的最远距离。首先(dp[u][0])(dp[u][1])是容易求的。然后我们考虑经过父亲的情况,设u是v的父亲,那么(dp[v][2]=max(dp[u][2], dp[v][0]+w[i]==dp[u][0]?dp[u][1]:dp[u][0]))

    我还考虑了这样的情况:情况。我蠢蠢的认为这样子的情况,(dp[u][1])用我的代码求出来是0,是不行的。然而。。它就应该是0。因为你走了u就不能走回头路了。所以(dp[u][1])的定义不应该是u这个节点走到子树中任意一个点的的次大距离,而应该是在所有经过子节点i的最大路径中次大的哪一个。蛤蛤,真是为自己的智商感到担忧。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int maxn=10005;
    
    class Graph{
    public:
        struct Edge{
            int to, next, v; Graph *bel;
            void set(int x, int y, Graph *g){
                to=x; next=y; bel=g; }
            inline int operator *(){ return to; }
            Edge& operator ++(){
                return *this=bel->edge[next]; }
        };
        void reset(){ //edge不用清零,因为最后跳到的结点是0
            memset(fir, 0, sizeof(fir));
            cntedge=0; edge[cntedge].to=0;
        }
        void addedge(int x, int y, int w){
            edge[++cntedge].set(y, fir[x], this);
            fir[x]=cntedge; edge[cntedge].v=w;
        }
        Edge& getlink(int x){ return edge[fir[x]]; }
    private:
        int cntedge, fir[maxn];
        Edge edge[maxn*2];
    };
    
    Graph g;
    int n, dp[maxn][3];
    
    void dfs1(int now, int par){
        Graph::Edge e=g.getlink(now);
        int tmp;
        for (; *e; ++e){
            if (*e==par) continue;
            dfs1(*e, now);
            tmp=dp[*e][0]+e.v;
            if (tmp>=dp[now][0]){
                dp[now][1]=dp[now][0];
                dp[now][0]=tmp;
            } else if (tmp>dp[now][1])
                dp[now][1]=tmp;
        }
    }
    
    void dfs2(int now, int par){
        Graph::Edge e=g.getlink(now);
        for (; *e; ++e){
            if (*e==par) continue;
            dp[*e][2]=max(dp[now][2],
                    dp[*e][0]+e.v==dp[now][0]?
                        dp[now][1]:dp[now][0])+e.v;
            dfs2(*e, now);
        }
    }
    
    int main(){
        while (~scanf("%d", &n)){
            memset(dp, 0, sizeof(dp));
            int x, y; g.reset();
            for (int i=2; i<=n; ++i){
                scanf("%d%d", &x, &y);
                g.addedge(i, x, y); g.addedge(x, i, y);
            }
            dfs1(1, 0);
            dfs2(1, 0);
            for (int i=1; i<=n; ++i)
                printf("%d
    ", max(dp[i][0], dp[i][2]));
        }
    }
    
  • 相关阅读:
    spring-boot-starter-actuator /info获取空信息
    我们每天都在做无用功?
    Net和Java基于zipkin的全链路追踪
    各大厂分布式链路跟踪系统架构对比
    淘宝npm镜像使用方法(转)
    你离架构师还有多远?
    该怎么向别人介绍你们的系统架构?
    java中用MessageFormat格式化json字符串用占位符时出现的问题can't parse argument number
    你必须要了解的大数据潮流下的机器学习及应用场景
    突破GitHub单个文件最大100M的限制 LFS
  • 原文地址:https://www.cnblogs.com/MyNameIsPc/p/7744814.html
Copyright © 2011-2022 走看看