• 蓝桥杯:结点选择


    问题描述
    有一棵 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的正整数

    没有上司的舞会问题

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    using namespace std;
    const int MAXN=100005;
    int w[MAXN];
    vector<int> tree[MAXN];
    int n;
    int dp[MAXN][2];
    int vis[MAXN];
    void dfs(int u)
    {
        vis[u]=1;
        dp[u][0]=0;
        dp[u][1]=w[u];
        int s0=0,s1=0;
        for(int i=0;i<tree[u].size();i++)
        {
            int v=tree[u][i];
            if(!vis[v])
            {
                dfs(v);
                s0+=max(dp[v][0],dp[v][1]);
                s1+=dp[v][0];
            }
        }
        dp[u][0]+=s0;
        dp[u][1]+=s1;
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&w[i]);
        
        for(int i=1;i<=n-1;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            tree[u].push_back(v);
            tree[v].push_back(u);
        }
        dfs(1);
        
        printf("%d
    ",max(dp[1][0],dp[1][1]));
        
        return 0;
    }
  • 相关阅读:
    IP通信基础学习第八周
    IP通信基础学习第七周(下)
    IP通信基础学习第七周(上)
    IP通信基础学习第六周(下)
    mysql 笔记
    一个不错的MYSQL数据库备份类,PHP版,一个文件,精简版
    Linux下apache日志(按日期存放)分析与状态查看方法
    呵呵
    docker-compose常用命令
    mysql 数据备份
  • 原文地址:https://www.cnblogs.com/program-ccc/p/5221932.html
Copyright © 2020-2023  润新知