zoukankan      html  css  js  c++  java
  • 算法训练 结点选择【树形动态规划】

    问题描述

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

    输入格式

    第一行包含一个整数 n 。

    接下来的一行包含 n 个正整数,第 i 个正整数代表点 i 的权值。

    接下来一共 n-1 行,每行描述树上的一条边。

    输出格式

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

    样例输入

    5

    1 2 3 4 5

    1 2

    1 3

    2 4

    2 5

    样例输出

    12

    样例说明

    选择3、4、5号点,权值和为 3+4+5 = 12 。

    数据规模与约定

    对于20%的数据, n <= 20。

    对于50%的数据, n <= 1000。

    对于100%的数据, n <= 100000。

    权值均为不超过1000的正整数。

    解题思路

    dp[1][u]+=dp[0][u_son];

    dp[0][u]+=max(dp[0][u_son],dp[1][u_son]);

    接触树形dp的第一道题!

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <stdlib.h>
    #include <cstring>
    #include <vector>
    #define inf 100005
    using namespace std;
    int w[inf];//记录各点权重    
    vector<int> G[inf];
    int d[2][inf];
    //d[1][i] 为取第i个节点的最大值
    //d[0][i] 为不取
    bool vis[inf];
    int n;//节点个数
    void dfs(int u) {
        vis[u] = 1;
        for (int i = 0; i < G[u].size(); i++) {
            int v = G[u][i];//u的第i个儿子
            if (vis[v])continue;
            dfs(v);
            d[1][u] += d[0][v];
            d[0][u] += max(d[0][v], d[1][v]);
        }
        d[1][u] += w[u];
    }
    int main() {
        scanf("%d", &n);
        for (int i = 1; i <= n; i++)
            scanf("%d", &w[i]);
        int a, b;
        for (int i = 0; i < n - 1; i++) {
            scanf("%d %d", &a, &b);
            G[a].push_back(b);
            G[b].push_back(a);
        }
        dfs(1);
        cout << max(d[0][1], d[1][1]);
        return 0;
    }


  • 相关阅读:
    分析模式的位置
    SAP .Net Connector for C#
    NETBPM开源工作流讲座
    BW处理链的时间为什么会每天推迟2秒钟?
    如何在SubScreen中取得上一screen中的值
    flash弹出窗口被ie屏蔽的解决方法
    用Eclipse 开发Flex (配置安装Flex插件)
    rtmp和http方式在播放flv方面的各自优势和劣势
    FMS4 P2P直播解决方案
    [AS3]URLLoader+URLRequest+JPGEncoder实现BitmapData图片数据保存
  • 原文地址:https://www.cnblogs.com/woxiaosade/p/10445842.html
Copyright © 2011-2022 走看看