zoukankan      html  css  js  c++  java
  • 牛客网 桂林电子科技大学第三届ACM程序设计竞赛 G.路径-带条件的树的直径变形-边权最大,边数偶数的树上的最长路径-树形dp

    链接:https://ac.nowcoder.com/acm/contest/558/G

    来源:牛客网

    路径

    小猫在研究树。
    小猫在研究路径。
    给定一棵N个点的树,每条边有边权,请你求出最长的一条路径,满足经过每个点最多一次,经过的边的条数为偶数,且边权和最大。
    请输出这个最大的边权和。

    输入描述:

    第一行一个正整数N,表示节点个数。

    接下来N−1行,第i行三个正整数

    ui,vi,wi,表示第i条边连接点ui,vi,边权为wi。

    输出描述:

    一行一个正整数,表示最大的边权和。
    示例1

    输入

    复制
    5
    1 2 5
    1 3 5
    2 4 5
    2 5 1
    

    输出

    复制
    10

    备注:

    1≤N≤10

    5

    ,1≤w

    i

    ≤10

    9

    ,保证输入数据形成一棵树。

    一开始智障了,以为直接搜索跑个树的直径然后删边就可以。最后发现想的太简单了,只能用树dp写。

    二维dp,0表示偶数条边情况下,1表示奇数。

    因为按边算,叶子节点为0,赋值0,1的赋值-inf,往上,到父节点,父节点的状态为,父亲的偶数情况为儿子节点的奇数情况+边权,奇数情况也一样。

    dp[u][0]表示从叶子节点到当前节点u,偶数条边的最大值,奇数同理。到根节点的时候,偶数情况有两种:1.两个奇数条边的子树的链的和。2.两个偶数条边的子树的链的和。

    代码:

     1 //G-树上的dp
     2 #include<bits/stdc++.h>
     3 using namespace std;
     4 typedef long long ll;
     5 const int maxn=1e5+10;
     6 const ll inf=1e18+10;
     7 
     8 ll dp[maxn+10][2];
     9 
    10 struct node{
    11     int to;
    12     ll val;
    13 };
    14 
    15 int n;
    16 ll ans=-inf;
    17 vector<node> G[maxn<<1];
    18 bool vis[maxn];
    19 
    20 void dfs(int u)
    21 {
    22     vis[u]=true;
    23     for(int i=0;i<G[u].size();i++){
    24         int v=G[u][i].to;
    25         ll w=G[u][i].val;
    26         if(vis[v]) continue;
    27         dfs(v);
    28         //两个端点相连的 奇数+奇数 或者偶数+偶数的
    29         ans=max(ans,dp[u][1]+dp[v][0]+w);
    30         ans=max(ans,dp[u][0]+dp[v][1]+w);
    31         dp[u][1]=max(dp[u][1],dp[v][0]+w);
    32         dp[u][0]=max(dp[u][0],dp[v][1]+w);
    33     }
    34 }
    35 
    36 int main()
    37 {
    38     scanf("%d",&n);
    39     for(int i=1;i<n;i++){
    40         int u,v;ll w;
    41         scanf("%d%d%lld",&u,&v,&w);
    42         G[u].push_back({v,w});
    43         G[v].push_back({u,w});
    44     }
    45     memset(vis,false,sizeof(vis));
    46     for(int i=1;i<=n;i++){
    47         dp[i][0]=0;
    48         dp[i][1]=-inf;
    49     }
    50     dfs(1);
    51     cout<<ans<<endl;
    52 }
  • 相关阅读:
    setTimeout 理解
    Git 使用规范流程
    JavaScript异步编程 ( 一 )
    javaScript模块化一
    javascript 知识点坑
    javaScript闭包
    函数式编程
    JavaScript的68个技巧一
    MySql 隐式转换
    MySQL优化
  • 原文地址:https://www.cnblogs.com/ZERO-/p/10733538.html
Copyright © 2011-2022 走看看