• P1131 [ZJOI2007]时态同步


    传送门

    DP

    题目讲得很清楚"对于电路板的任何两个节点,都存在且仅存在一条通路".

    所以电路板是一颗树

    题目要求叶子节点时态一致

    如果从根开始枚举时间肯定超时

    考虑反过来

    从叶子节点开始考虑时间

    容易注意到

    对于一个子树的根 root 来说

    不管上面用了多久把信息传下来

    要让它的儿子收到信息的时间相同

    必须让 root 到各个儿子的距离相等

    如果一个子树已经调好了

    那么以后也不会再去更改

    无后效性

    所以考虑DP

    对于一个非叶子节点,要让它到各个儿子的距离相等

    那么显然最节省的方案就是

    让它到各个儿子的距离改成它最远的儿子的距离

    所以得出状态转移方程:

    设f[ i ]为 当以 i 为根的子树的时态同步时,从它的叶子到 i 需要的时间

    f[ i ]=max(f[ i ],f[ u ]+dis[ i ][ u ]) ( u为 i 的儿子,dis[ i ][ u ]为 i 到 u 的距离)

    而答案就在更新f[ i ] 的时候顺便累加一下就好了

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    using namespace std;
    inline int read()
    {
        int x=0,f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9')
        {
            if(ch=='-') f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            x=(x<<1)+(x<<3)+(ch^48);
            ch=getchar();
        }
        return x*f;
    }
    const int N=500007;
    vector <int> v[N],g[N]; //用vector 存图,反正不会超时
    int n,rt;//rt 为根节点
    long long f[N],ans;//f如上所述,ans存答案
    inline void dfs(int x,int fa)//fa 存 x 的父亲
    {
        int len=v[x].size();
        for(int i=0;i<len;i++)
        {
            int u=v[x][i];
            if(u==fa) continue;//如果是父亲就跳过
            dfs(u,x);//否则先更新儿子节点
            f[x]=max(f[x],f[u]+g[x][i]);//更新当前节点
        }
        for(int i=0;i<len;i++)
        {
            int u=v[x][i];
            if(u==fa) continue;//如果是父亲就跳过
            ans+=(f[x]-f[u]-g[x][i]);//累加答案
        }
    }
    int main()
    {
        int a,b,c;
        cin>>n>>rt;
        for(int i=1;i<n;i++)
        {
            a=read(); b=read(); c=read();
            v[a].push_back(b); g[a].push_back(c);
            v[b].push_back(a); g[b].push_back(c);
        }//存边
        dfs(rt,rt);
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    新年新气象,用新年的喜庆来迎接的生活
    vs2005中如何发布网站及打包web项目生成安装文件
    完整打印页面控件的解决方案
    vi使用体会
    向ATL DLL中传递C++对象
    CentOS 5.3配置软件源以及CVS服务器
    堆上多维数组的内存管理
    物理坐标与逻辑坐标
    好友列表的实现
    在STL中处理对象指针
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/9523875.html
Copyright © 2020-2023  润新知