zoukankan      html  css  js  c++  java
  • 蓝桥杯 生命之树【树状dp】

    生命之树

    在X森林里,上帝创建了生命之树。

    他给每棵树的每个节点(叶子也称为一个节点)上,

    都标了一个整数,代表这个点的和谐值。

    上帝要在这棵树内选出一个非空节点集S,

    使得对于S中的任意两个点a,b,都存在一个点列 {a, v1, v2, ..., vk, b}

    使得这个点列中的每个点都是S里面的元素,且序列中相邻两个点间有一条边相连。

    在这个前提下,上帝要使得S中的点所对应的整数的和尽量大。

    这个最大的和就是上帝给生命之树的评分。

    经过atm的努力,他已经知道了上帝给每棵树上每个节点上的整数。

    但是由于 atm 不擅长计算,他不知道怎样有效的求评分。

    他需要你为他写一个程序来计算一棵树的分数。

    「输入格式」

    第一行一个整数 n 表示这棵树有 n 个节点。

    第二行 n 个整数,依次表示每个节点的评分。

    接下来 n-1 行,每行 2 个整数 u, v,表示存在一条 u 到 v 的边。

    由于这是一棵树,所以是不存在环的。

    「输出格式」

    输出一行一个数,表示上帝给这棵树的分数。

    「样例输入」

    5

    1 -2 -3 4 5

    4 2

    3 1

    1 2

    2 5

    「样例输出」

    8

    题目分析

    这是一道树状dp题,每个节点只有两种决策,选与不选,因此我们建立一个数组。

    int dp [ N ][2] ;其中,dp[ i ][ 1 ]表示选第i个节点的情况下最大分数,dp [ i ][ 0 ]为不选的情况下的最大分数。

    d[ i ][ 0 ] = t,那么存在一个 i 的子节点 j,使得 d[ j ][ 1 ] 的值也为 t , 因此我们可以让所有的d[ i ] [ 0] = 0

    这样一来,状态转移方程很容易写出来:

    [{ m{d}}[i][1] = sum {max (d[j][1],d[j][0])}  + w[i]]

    [{ m{d}}[i][1] = sum {max (d[j][1],{ m{0}})}  + w[i]]

    其实这样子,大家就能发现,dp[i][0]没有用到,dp设成一维的,也是可以解决这个问题的。

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    using namespace std;
    int w[100005];
    int vist[100005];
    int dp[100005];
    int n;
    int ans = -0x3f3f3f3f;
    vector<int> G[100005];
    
    void dfs(int u){
    	dp[u] = w[u];
    	vist[u] = 1;
    	for (int i = 0; i < G[u].size(); i++){
    		if (!vist[G[u][i]]){//未访问的节点 才是 他的子节点
    			dfs(G[u][i]);
    			dp[u] += max(dp[G[u][i]], 0);
    		}
    	}
    	ans = max(dp[u], ans);
    }
    int main(){
    	cin >> n;
    	int i;
    	for (i = 1; i <= n; i++)
    		cin >> w[i];
    	int a, b;
    	for (i = 1; i < n; i++){
    		scanf("%d %d", &a, &b);
    		G[a].push_back(b);
    		G[b].push_back(a);
    	}
    	dfs(1);
    	cout << ans << endl;
    	return 0;
    }
  • 相关阅读:
    SCSI contrller的几种类型的区别
    ScaleIO与XtremSW Cache如何集成呢?
    如何强制使用某一大小的包去ping某个IP地址?
    如何查看ETW Trace?
    图像卷积与滤波的一些知识点(转)
    tensorflow serving 编写配置文件platform_config_file的方法
    python在linux的报错集锦
    某些数组和字符串类型转换(转)
    系统安装-007 CentOS7yum源添加、删除及其yum优化(转)
    Error:Failed to resolve: android.arch.core:common:1.1.0
  • 原文地址:https://www.cnblogs.com/woxiaosade/p/10580056.html
Copyright © 2011-2022 走看看