• [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;
    }
    呆码
  • 相关阅读:
    Sql语句创建表
    刷新、关闭等误操作造成当前页面信息的丢失的解决方案
    asp.net文本框中只允许用户输入数字
    为每个用户创建文件夹,并实现图片上传
    在updatepanel中使用fileupload控件
    解决弹出提示框后字体变大的BUG
    SQL 2005新增的几个函数之学习
    .net实现单张图片的上传
    数据分页
    所谓三门问题
  • 原文地址:https://www.cnblogs.com/zzzyc/p/9029174.html
Copyright © 2020-2023  润新知