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
  • 相关阅读:
    pytorch的常用接口、操作、注意事项
    pytorch 中conv1d操作
    NLP基本知识点和模型
    深度学习基础理论知识
    对交叉验证的理解
    阅读深度学习论文的一些技巧
    机器学习和深度学习入门总结
    架构思考-业务快速增长时的容量问题
    系统梳理一下锁
    稳定性五件套-限流的原理和实现
  • 原文地址:https://www.cnblogs.com/kiwi-bird/p/3294487.html
Copyright © 2011-2022 走看看