zoukankan      html  css  js  c++  java
  • 旅行-树形DP

    60分:对于每个点为根的情况做一遍DP,s,g表示从小C,A从这个点走出去的路程

    100分,树形DP对于每个点的路径可以由其父亲转来,这样的DP就需要比较好的技巧了。

    以前有道差不多的叫星座的题目来着。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define ll long long 
    int n,x,y,z,num;
    int head[300005],next[600005],to[600005],val[600005];
    ll f[300005],g[300005],fs[300005],gs[300005],ans[300005]; 
    void add_edge(int u,int v,int c)
    {
        to[++num]=v;
        val[num]=c;
        next[num]=head[u];
        head[u]=num; 
    }
    void dp(int u,int fa)
    {
        bool son=0;
        for(int edge=head[u];edge;edge=next[edge])
        if(to[edge]!=fa)
        {
            son=1;
            dp(to[edge],u);
            f[u]=max(f[u],g[to[edge]]+val[edge]);
            g[u]=min(g[u],f[to[edge]]+val[edge]);
        }
        if(!son) g[u]=0;
     }
    void DP(int u,int fa)
    {
        ll s1=1e16,s2=1e16;
        int p1=0,p2=0;
        for(int edge=head[u];edge;edge=next[edge])
        if(to[edge]!=fa)
        {
            if(f[to[edge]]+val[edge]<s1)
            {
                s2=s1;
                s1=f[to[edge]]+val[edge];
                p2=p1;
                p1=to[edge];
            }else
            if(f[to[edge]]+val[edge]<s2)
            {
                s2=f[to[edge]]+val[edge];
                p2=to[edge];
            }
        }
        for(int edge=head[u];edge;edge=next[edge])
        if(to[edge]!=fa)
        {
            if(p1!=to[edge])
            fs[to[edge]]=min(fs[to[edge]],s1+val[edge]);else
            fs[to[edge]]=min(fs[to[edge]],s2+val[edge]);
            fs[to[edge]]=min(fs[to[edge]],gs[u]+val[edge]);
        }
        ll g1=0,g2=0;
        p1=0,p2=0;
        for(int edge=head[u];edge;edge=next[edge])
        if(to[edge]!=fa)
        {
            if(g[to[edge]]+val[edge]>g1)
            {
                g2=g1;
                g1=g[to[edge]]+val[edge];
                p2=p1;
                p1=to[edge];
            }else
            if(g[to[edge]]+val[edge]>g2)
            {
                g2=g[to[edge]]+val[edge];
                p2=to[edge];
            }
        }
        for(int edge=head[u];edge;edge=next[edge])
        if(to[edge]!=fa)
        {
            if(p1!=to[edge])
            gs[to[edge]]=max(gs[to[edge]],g1+val[edge]);else
            gs[to[edge]]=max(gs[to[edge]],g2+val[edge]);
            gs[to[edge]]=max(gs[to[edge]],fs[u]+val[edge]);
        }
        for(int edge=head[u];edge;edge=next[edge])
        if(to[edge]!=fa)
        {
            ans[to[edge]]=max(fs[to[edge]],f[to[edge]]);
            DP(to[edge],u);
        }
     } 
    int main()
    {
         scanf("%d",&n);
         for(int i=1;i<=n-1;i++)
         {
             int u,v,c;
             scanf("%d %d %d",&u,&v,&c);
             add_edge(u,v,c);
             add_edge(v,u,c);
        }
         for(int i=1;i<=n;i++) 
        {
            f[i]=gs[i]=0;
            g[i]=fs[i]=1e16;
        }
        dp(1,0);
           
        ans[1]=f[1];gs[1]=1e16;fs[1]=0;
        DP(1,0);
        for(int i=1;i<=n;i++)
        printf("%lld
    ",ans[i]);
    }
  • 相关阅读:
    开发中的一些总结2
    XML与DataTable/DataSet互转(C#) 把数据库中表的内容转存为XML文件
    闲来无事。。。。
    一:Js的Url中传递中文参数乱码问题,重点:encodeURI编码,decodeURI解码:
    20120301 14:10 js函数内部实现休眠
    设为首页和收藏本站的代码
    Jquery实现对a标签改变选中的背景色 支持多选 再次点击背景色消失
    asp.net上传图片并生成等比例缩略图(.Net自带函数完成)
    类中只有 成员变量 和 一个成员函数表
    CListCtrl 使用技巧
  • 原文地址:https://www.cnblogs.com/dancer16/p/7327803.html
Copyright © 2011-2022 走看看