zoukankan      html  css  js  c++  java
  • 结点选择(树形DP)

    Description

    有一棵 n 个节点的树,树上每个节点都有一个正整数权值。如果一个点被选择了,那么在树上和它相邻的点都不能被选择。求选出的点的权值和最大是多少?

    Input

    接下来的一行包含 n 个正整数,第 i 个正整数代表点 i 的权值。
    接下来一共 n-1 行,每行描述树上的一条边。

    Output

    输出一个整数,代表选出的点的权值和的最大值。

    Sample Input

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

    Sample Output

    12

    HINT

    样例说明
    选择3、4、5号点,权值和为 3+4+5 = 12 。
    数据规模与约定
    对于20%的数据, n <= 20。
    对于50%的数据, n <= 1000。
    对于100%的数据, n <= 100000。
    权值均为不超过1000的正整数。

    经典树形DP

    用dp[i][0]表示不选择i点时,i点及其子树能选出的最大权值,dp[i][1]表示选择i点时,i点及其子树的最大权值。

    对于叶子结点:
    dp[k][0] = 0;
    dp[k][1] = k点权值;


    对于非叶子结点:
    dp[i][0] =∑max(dp[j][0], dp[j][1]); (j是i的儿子)
    dp[i][1] = i点权值 +∑dp[j][0]; (j是i的儿子)

    最后树的最大权值即为:max(dp[1][0], dp[1][1])。(要么不包括根结点,要么包括根结点)

     

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <iostream>
     4 #include <string>
     5 #include <math.h>
     6 #include <algorithm>
     7 #include <vector>
     8 #include <stack>
     9 #include <queue>
    10 #include <set>
    11 #include <map>
    12 #include <sstream>
    13 const int INF=0x3f3f3f3f;
    14 typedef long long LL;
    15 using namespace std;
    16 
    17 int n;
    18 int dp[100005][2];
    19 int vis[100005];
    20 vector<int> vt[100005];
    21 
    22 void DFS(int st)
    23 {
    24     vis[st]=1;
    25     for(int i=0;i<vt[st].size();i++)
    26     {
    27         int to=vt[st][i];
    28         if(!vis[to])
    29         {
    30             DFS(to);
    31             dp[st][1]+=dp[to][0];
    32             dp[st][0]+=max(dp[to][0],dp[to][1]);
    33         }
    34     }
    35 }
    36 
    37 int main()
    38 {
    39     scanf("%d",&n);
    40     for(int i=1;i<=n;i++)
    41         scanf("%d",&dp[i][1]);
    42     for(int i=1;i<=n-1;i++)
    43     {
    44         int a,b;
    45         scanf("%d %d",&a,&b);
    46         vt[a].push_back(b);
    47         vt[b].push_back(a);
    48     }
    49     DFS(1);
    50     printf("%d
    ",max(dp[1][0],dp[1][1]));
    51     return 0;
    52 }

    -

  • 相关阅读:
    世界本就很简单-云计算
    世界本就很简单-集群
    Linux虚拟机连接网络
    定时任务删除日志文件
    fiddler篡改请求数据
    Jmeter-线程日志查看
    Jmeter-JDBC Request
    Jmeter-查看结果树
    Jmeter-聚合报告
    Jmeter-参数化
  • 原文地址:https://www.cnblogs.com/jiamian/p/12194258.html
Copyright © 2011-2022 走看看