• 小火山的宝藏收益 多校训练2(小火山专场) poj(邻接表+DFS)


    http://acm.zzuli.edu.cn/zzuliacm/problem.php?id=1907

    Description
    
      
      进去宝藏后, 小火山发现宝藏有N个房间,且这n个房间通过N-1道门联通。
      每一个房间都有一个价值为Ai的宝藏, 但是每一个房间也都存在一个机关。如果小火山取走了这个房间的宝藏,那么这个房间通往其他房间的门就永远打不开了,也就是说后面的宝藏小火山是得不到了(进入这个房间的门是不会关闭的,小火山还是可以回去的);如果小火山不取这个宝藏,而是去打开通往另一房间的门,那么这个房间的宝藏就会消失, 小火山就得不到这个房间的宝藏。
      不过,小火山已经有了藏宝图,知道每一个房间的宝藏的价值,现在想请你帮小火山算一下,他最多能获得多少钱去买股票?
    Input
    
    输入第一行是一个整数T(T <= 50), 表示一共有T组数据。
    对于每一组数据,第一行是两个数N, S(1 <= N <= 10000, 1 <= S <= N), N代表有N个房间, S代表小火山进去宝藏后的
    起始房间(小火山怎么进入起始房间不重要),第二行是N个数,代表每个房间宝藏的价值, 随后N-1行, 每行两个数A, B, 代表
    A, B这两个房间联通。
    Output
    
    对于每一组数据输出一个整数, 代表小火山能获得的最大钱数。
    
    Sample Input
    
    2
    1 1
    20
    3 1
    4 5 6
    1 2
    2 3
    Sample Output
    
    20
    6
    

      

    分析:一开始比较纠结到底要怎么处理取该房间宝藏其他房间门就关闭这一点。后来想通了。。

    举例子来说,取一个点,把与之相邻的点的和加一起与这个点本身的值进行比较,哪个大取哪个即可。(简单的例子,与之相邻的点都没有其他相邻的点了)

    若与之相邻的点还有其他的点,那么方法还是一样,按照这个方法进行递归即可。

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <string>
    #include <vector>
    #include <algorithm>
    #include <map>
    #include <queue>
    #include <stack>
    #include <math.h>
    
    using namespace std;
    
    #define met(a, b) memset(a, b, sizeof(a))
    #define maxn 11000
    #define INF 0x3f3f3f3f
    const int MOD = 1e9+7;
    
    typedef long long LL;
    int cnt, head[maxn], v[maxn], value[maxn];
    
    struct node
    {
        int u, v, next;
    }maps[4*maxn];
    
    void Add(int u, int v)
    {
        maps[cnt].v = v;
        maps[cnt].next = head[u];
        head[u] = cnt ++;
    }
    
    int DFS(int s)
    {
        int sum = 0;
        for(int i=head[s]; i!=-1; i=maps[i].next)
        {
            int p = maps[i].v;
            if(!v[p])
            {
                v[p] = 1;
                sum += DFS(p);
            }
        }
        
        return max(sum, value[s]);
    }
    
    int main()
    {
        int T, a, b, s, n;
    
        scanf("%d", &T);
    
        while(T --)
        {
            scanf("%d %d", &n, &s);
    
            for(int i=1; i<=n; i++)
                scanf("%d", &value[i]);
    
            memset(head, -1, sizeof(head));
            cnt = 0;
    
            for(int i=1; i<n; i++)
            {
                scanf("%d %d", &a, &b);
                Add(a, b);
                Add(b, a);
            }
    
            memset(v, 0, sizeof(v));
            v[s] = 1;
    
            int ans = DFS(s);
    
            printf("%d
    ", max(ans, value[s]));
    
        }
        return 0;
    }
    
    
    /*
    1
    5 2
    5 5 2 1 5
    1 5
    1 2
    2 3
    2 4
    */
    View Code
  • 相关阅读:
    C语言实现数据机构链表的基本操作(从键盘输入生成链表、读取数组生成链表)
    MySql-8.0.x免安装版下载与配置,Navicat打开数据库链接报错1251的解决办法
    win10彻底卸载和删除MySql
    Linux/(centos、unix等)的ssh双向免密登录原理和实现
    笔趣阁小说-圣墟-爬虫源代码
    C语言实现顺序表的基本操作(从键盘输入 生成线性表,读txt文件生成线性表和数组生成线性表----三种写法)
    python语言开发环境配置
    Python闭包详解
    结对作业
    Java第九次作业——接口回调
  • 原文地址:https://www.cnblogs.com/daydayupacm/p/5760108.html
Copyright © 2020-2023  润新知