zoukankan      html  css  js  c++  java
  • 中南大学oj 1317 Find the max Link 边权可以为负的树上最长路 树形dp 不能两遍dfs

    http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1317
    经典问题:
    树上最长路,边权可以为负值的,树形dp,不能用两边dfs。
    反例:
    5 4
    1 2 2
    2 3 1
    2 4 -100
    4 5 10
    写树形dp的时候,WA了好多次,错误在于:
    记录单链的时候,一个节点的最长单链不一定等于:边权+孩子的最长单链
    还可以不选孩子,只要边权就行!!!!!!
    如果边权非负的话,就是 边权+孩子的最长单链 了。

    思路:

      dp[u][0],记录的是以u为根结点的子树中的最长路

      dp[u][1],记录的是以u为起点的向下的一条最长链

    转移时:

      a记录的是max{ dp[sons][0] } 

      b和c记录的分别是dp[sons][1]的最大值和次大值

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<vector>
     4 using namespace std;
     5 const int N = 50005;
     6 typedef long long LL;
     7 LL inf = N * 100000ll;
     8 
     9 inline LL max(LL a,LL b)    {return a>b?a:b;}
    10 inline LL max(LL a,LL b,LL c)    {return (a>b?a:b)>c?(a>b?a:b):c;}
    11 
    12 LL dp[N][2];
    13 vector<int> G[N];
    14 struct edge
    15 {
    16     int to,w;
    17 }edges[2*N];
    18 
    19 void dfs(int u,int fa)
    20 {
    21     int sz=G[u].size(),v,w;
    22     LL temp;
    23     LL a=-inf,b=-inf,c=-inf;
    24     for(int i=0;i<sz;i++)
    25     {
    26         v = edges[G[u][i]].to;
    27         w = edges[G[u][i]].w;
    28         if( v!=fa )
    29         {            
    30             dfs(v,u);
    31             temp = max(dp[v][1]+w,w);
    32             a = max(a,dp[v][0]);
    33             if( temp > b )
    34             {
    35                 c = b;
    36                 b = temp;
    37             }
    38             else if( temp > c )
    39                 c = temp;            
    40         }
    41     }
    42     dp[u][0]=max(a,b,b+c);
    43     dp[u][1]=b;
    44 }
    45 
    46 int main()
    47 {
    48     int n,m;
    49     int u,v,w;
    50     
    51     while( ~scanf("%d%d",&n,&m) )
    52     {
    53         for(int i=1;i<=n;i++)    G[i].clear();
    54         for(int i=1;i<=m;i++)
    55         {
    56             scanf("%d%d%d",&u,&v,&w);
    57             edges[i].to = v;
    58             edges[i+m].to = u;
    59             edges[i].w = edges[i+m].w = w;
    60             G[u].push_back(i);
    61             G[v].push_back(i+m);
    62         }
    63         dfs(1,0);
    64         LL ans = -inf;
    65         for(int i=1;i<=n;i++)
    66             ans = max(ans,dp[i][0]);
    67         printf("%lld
    ",ans);
    68         //cout<<ans<<endl;
    69     }
    70     return 0;
    71 }
    View Code
  • 相关阅读:
    10 个深恶痛绝的 Java 异常。。
    为什么公司宁愿 25K 重新招人,也不给你加到 20K?原因太现实……
    推荐一款代码神器,代码量至少省一半!
    Spring Cloud Greenwich 正式发布,Hystrix 即将寿终正寝。。
    hdu 3853 LOOPS(概率 dp 期望)
    hdu 5245 Joyful(期望的计算,好题)
    hdu 4336 Card Collector(期望 dp 状态压缩)
    hdu 4405 Aeroplane chess(概率+dp)
    hdu 5036 Explosion(概率期望+bitset)
    hdu 5033 Building (单调栈 或 暴力枚举 )
  • 原文地址:https://www.cnblogs.com/kiwi-bird/p/3294487.html
Copyright © 2011-2022 走看看