zoukankan      html  css  js  c++  java
  • [ZJOI2007]时态同步

    这个题。。。一眼树形DP???

    我们通过模拟几组数据可以发现。。。

    其实只需要保证每一棵树的边权之和加起来相等。。。

    那么这些子树组成的一棵大树。。。就是最终我们要求的。。。

    既然这样。。。

    我们第一遍需要从叶子结点推到根节点。。。找到这些最大值。。。

    我们便于理解。。。这里将树分级。。。叶子结点为1级。。。比它大一号的为2级。。。

    以此类推。。。

    然后依次枚举每一个以当前节点为根的n级子树的权值和它所在n+1级子树要达到的最大值

    这样就可以统计出答案了。。。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 500010
    using namespace std;
    
    int n,s,x,y,z,f[maxn],head[maxn<<1],num;
    long long ans;
    bool use[maxn];
    
    struct asd{
        int nxt;
        int to;
        int dis;
    } a[maxn<<1];
    
    inline void add(int x,int y,int z)
    {
        a[++num].nxt=head[x];
        a[num].to=y;
        a[num].dis=z;
        head[x]=num;
    }
    
    inline void dfs1(int u)
    {
        use[u]=1;
        for(int i=head[u];i;i=a[i].nxt)
        {
            int to=a[i].to;
            if(!use[to])
            {
                dfs1(to);
                f[u]=max(f[u],f[to]+a[i].dis);
            }
        }
    }
    
    inline void dfs2(int u)
    {
        use[u]=1;
        for(int i=head[u];i;i=a[i].nxt)
        {
            int to=a[i].to;
            if(!use[to])
            {
                dfs2(to);
                ans+=f[u]-f[to]-a[i].dis;
            }
        }
    }
    
    int main()
    {
        scanf("%d%d",&n,&s);
        for(int i=1;i<=n-1;i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z); add(y,x,z);
        }
        dfs1(s);
        memset(use,0,sizeof(use));
        dfs2(s);
        printf("%lld
    ",ans);
        return 0;
    }
    呆码
  • 相关阅读:
    Primary key and Unique index
    Hash unique和Sort unique
    Oracle索引扫描算法
    Oracle预估的基数算法
    PGA突破pga_aggregate_target限制
    aix ipcs使用说明
    开窗函数和聚合函数区别
    【39.66%】【codeforces 740C】Alyona and mex
    【81.82%】【codeforces 740B】Alyona and flowers
    Android SDK离线安装
  • 原文地址:https://www.cnblogs.com/zzzyc/p/9029174.html
Copyright © 2011-2022 走看看