• HDU2196 Computer(树形DP)


    LightOJ1257一样,之前我用了树分治写了。其实原来这题是道经典的树形DP,感觉这个DP不简单。。

    • dp[0][u]表示以u为根的子树中的结点与u的最远距离
    • dp[1][u]表示以u为根的子树中的结点与u的次远距离

    这两个可以一遍dfs通过儿子结点转移得到。显然dp[0][u]就是u的一个可能的答案,即u往下走的最远距离,还缺一部分就是u往上走的最远距离:

    • dp[2][u]表示u往上走的最远距离

    对于这个的转移,分两种情况,是这样的:

    1. dp[2][v] = max( dp[0][u]+weight(u,v) , dp[2][u]+weight(u,v) ) (v是u的儿子 且 u往下走的最远距离不经过v)
    2. dp[2][v] = max( dp[1][u]+weight(u,v) , dp[2][u]+weight(u,v) ) (v是u的儿子 且 u往下走的最远距离经过v)

    再一遍dfs就能得到。每个u的答案就是max(dp[0][u],dp[2][u]);

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 #define MAXN 11111
     6 struct Edge{
     7     int v,w,next;
     8 }edge[MAXN<<1];
     9 int NE,head[MAXN];
    10 void addEdge(int u,int v,int w){
    11     edge[NE].v=v; edge[NE].w=w;
    12     edge[NE].next=head[u]; head[u]=NE++;
    13 }
    14 long long d[3][MAXN];
    15 int idx[MAXN];
    16 void dfs0(int u,int fa){
    17     long long mx0=0,mx1=0;
    18     for(int i=head[u]; i!=-1; i=edge[i].next){
    19         int v=edge[i].v;
    20         if(v==fa) continue;
    21         dfs0(v,u);
    22         if(mx0<=d[0][v]+edge[i].w) mx1=mx0,mx0=d[0][v]+edge[i].w,idx[u]=v;
    23         else if(mx1<d[0][v]+edge[i].w) mx1=d[0][v]+edge[i].w;
    24         else if(mx1<d[1][v]+edge[i].w) mx1=d[1][v]+edge[i].w;
    25     }
    26     d[0][u]=mx0; d[1][u]=mx1;
    27 }
    28 void dfs1(int u,int fa){
    29     for(int i=head[u]; i!=-1; i=edge[i].next){
    30         int v=edge[i].v;
    31         if(v==fa) continue;
    32         if(idx[u]==v) d[2][v]=max(d[1][u]+edge[i].w,d[2][u]+edge[i].w);
    33         else d[2][v]=max(d[0][u]+edge[i].w,d[2][u]+edge[i].w);
    34         dfs1(v,u);
    35     }
    36 }
    37 int main(){
    38     int n,a,b;
    39     while(~scanf("%d",&n)){
    40         NE=0;
    41         memset(head,-1,sizeof(head));
    42         for(int i=2; i<=n; ++i){
    43             scanf("%d%d",&a,&b);
    44             addEdge(i,a,b); addEdge(a,i,b);
    45         }
    46         memset(d,0,sizeof(d));
    47         dfs0(1,1);
    48         dfs1(1,1);
    49         for(int i=1; i<=n; ++i){
    50             printf("%lld
    ",max(d[0][i],d[2][i]));
    51         }
    52     }
    53     return 0;
    54 }
  • 相关阅读:
    ASP.NET中如何防范SQL注入式攻击?(转)
    打开D盘时速度奇慢?
    Visual Studio 2008 下载地址
    如何利用XML文件,做为配置参数?
    如何将一个表中的数据INSERT INTO 到另一个表中?
    拖延交货或惹万人诉讼 消费者称戴尔态度恶劣
    NHibernate Linq中Null值排序的解决方法
    NHibernate3剖析:Query篇之NHibernate.Linq标准查询
    Nhibernate出现No row with the given identifier exists问题的产生原因及解决方法
    Nhibernate使用动态Expression的问题解决
  • 原文地址:https://www.cnblogs.com/WABoss/p/5267488.html
Copyright © 2020-2023  润新知