• 树的直径 树形dp+2次dfs



     

    题目描述

    给定一棵树 T ,树 T 上每个点都有一个权值。

    定义一颗树的子链的大小为:这个子链上所有结点的权值和 。

    请在树 T 中找出一条最大的子链并输出。

    输入描述:

     
     

    第一行输入一个 n,1≤n≤105。

    接下来一行包含n个数,对于每个数 ai,−10^5≤ai≤10^5,表示 i 结点的权值。

    接下来有n-1行,每一行包含两个数u,v( 1≤u,v≤n , u != v),表示u与v之间有一条边。

    输出描述:

     
     

    仅包含一个数,表示我们所需要的答案。

    示例1

    输入

    5
    2 -1 -1 -2 3
    1 2
    2 3
    2 4
    2 5

    输出

    4

    说明

    样例中最大子链为1 -> 2 -> 5

    备注:

    一个结点,也可以称作一条链

     树形dp

    如果值在边上的话

    1. void DP(int u,int pa)
    2. {
    3. dp[u]=0;
    4. for(int i=h[u];i;i=ne[i])
    5. {
    6. int v=e[i];
    7. if(v==pa) continue;
    8. DP(v,u);
    9. ans=max(ans,dp[u]+dp[v]+dis[i]);
    10. dp[u]=max(dp[u],dp[v]+dis[i]);
    11. }
    12. }

    如果值在点上的话

    1. #include<bits/stdc++.h>
    2. using namespace std;
    3. typedef long long ll;
    4. const int INF =0x3f3f3f3f;
    5. const int N=1e5+10;
    6. int n;
    7. ll idx,e[N*2],h[N],ne[2*N],w[N],dp[N],ans;
    8. bool vis[N];
    9. void add(int x,int y)
    10. {
    11. e[idx]=y;
    12. ne[idx]=h[x];
    13. h[x]=idx++;
    14. }
    15. void dfs(int x)
    16. {
    17. dp[x]=w[x];
    18. vis[x]=1;
    19. ans=max(ans,w[x]);
    20. for(int i=h[x]; ~i; i=ne[i])
    21. {
    22. int j=e[i];
    23. if(vis[j])continue;
    24. dfs(j);
    25. ans=max(ans,dp[x]+dp[j]);
    26. dp[x]=max(dp[x],dp[j]+w[x]);
    27. }
    28. }
    29. int main()
    30. {
    31. ios::sync_with_stdio(false);
    32. cin.tie(0);
    33. cout.tie(0);
    34. cin>>n;
    35. memset(h,-1,sizeof h);
    36. ans=-INF;
    37. for(int i=1; i<=n; i++)
    38. {
    39. cin>>w[i];
    40. }
    41. for(int i=1; i<=n-1; i++)
    42. {
    43. int u,v;
    44. cin>>u>>v;
    45. add(u,v);
    46. add(v,u);
    47. }
    48. dfs(1);
    49. cout<<ans;
    50. return 0;
    51. }

    两次dfs

    1. #include<bits/stdc++.h>
    2. using namespace std;
    3. typedef long long ll;
    4. const int INF =0x3f3f3f3f;
    5. const int N=1e5+10;
    6. int n,pos;
    7. ll idx,e[N*2],h[N],ne[2*N],w[N],dp[N],ans;
    8. bool vis[N];
    9. void add(int x,int y)
    10. {
    11. e[idx]=y;
    12. ne[idx]=h[x];
    13. h[x]=idx++;
    14. }
    15. void dfs(int now,ll x)
    16. {
    17. vis[now]=1;
    18. if(ans<x)
    19. {
    20. ans=x;
    21. pos=now;
    22. }
    23. for(int i=h[now]; ~i; i=ne[i])
    24. {
    25. int j=e[i];
    26. if(vis[j])continue;
    27. dfs(j,x+w[j]);
    28. }
    29. }
    30. int main()
    31. {
    32. ios::sync_with_stdio(false);
    33. cin.tie(0);
    34. cout.tie(0);
    35. cin>>n;
    36. memset(h,-1,sizeof h);
    37. ans=-INF;
    38. for(int i=1; i<=n; i++)
    39. {
    40. cin>>w[i];
    41. }
    42. for(int i=1; i<=n-1; i++)
    43. {
    44. int u,v;
    45. cin>>u>>v;
    46. add(u,v);
    47. add(v,u);
    48. }
    49. dfs(1,w[1]);
    50. //cout<<ans;
    51. memset(vis,0,sizeof vis);
    52. dfs(pos,w[pos]);
    53. cout<<ans;
    54. return 0;
    55. }

     

  • 相关阅读:
    【重识云原生】第六章容器6.1.8节——Docker核心技术UnionFS
    基于51单片机的音乐盒播放器proteus仿真
    Web 端项目系统访问页面很慢,后台数据返回很快,网络也没问题,是什么导致的呢?
    java入门,登录注册案例
    用Python自动生成 图文并茂的数据分析 报告
    SwiftUI教程之如何在 Xcode 14 中创建曲线导航栏动画
    【面试题 - spring】二
    STM32踩坑:LAN8720未接网线,上电后再接网线,网络模块无法正常使用
    学术论文写作
    python将pdf转为txt
  • 原文地址:https://blog.csdn.net/m0_61949623/article/details/126671478