• zzuli---1907---


    题目链接: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 HINT Source

    zzuli

    analyse:

    进入一个房间后有两种选择:

    1>拿走此房间宝藏,后面的不要了;

    2>此房间宝藏放弃,拿走与此房间相连的所有其他房间的宝藏;

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <cmath>
    #include<vector>
    #include<queue>
    #include<algorithm>
    
    using namespace std;
    typedef long long LL;
    
    const int maxn=50009;
    const int INF=0x3f3f3f3f;
    const int mod=2009;
    
    int head[maxn];
    int value[maxn];
    int vis[maxn];
    int n, k;
    
    struct node
    {
        int v, next;
    } maps[maxn<<2];
    
    void Add(int u, int v)
    {
        maps[k].v=v;
        maps[k].next=head[u];
        head[u]=k++;
    }
    
    int DFS(int s)
    {
        int sum=0;
        for(int i=head[s]; i!=-1; i=maps[i].next)
        {
            int v=maps[i].v;
            if(!vis[v])
            {
                vis[v]=1;
                sum+=DFS(v);
            }
        }
        return max(sum, value[s]);
    }
    int main()
    {
        int T, s;
        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));
            k=0;
            for(int i=1; i<n; i++)
            {
                int a, b;
                scanf("%d %d", &a, &b);
                Add(a, b);
                Add(b, a);
            }
    
            memset(vis, 0, sizeof(vis));
            vis[s]=1;
            int ans=DFS(s);
            printf("%d
    ", max(ans, value[s]));
        }
        return 0;
    }
  • 相关阅读:
    12月19号 init和class
    12月18号 property关键字
    12月18号 属性property
    12月17号 类和对象
    12月17号 OC语言准备
    12月16号 文件操作
    12月16号 双链表
    12月15号 单链表
    2015.12.07 ATM
    2015.12.03 命名规范 输入输出 运算符 条件语句 循环语句
  • 原文地址:https://www.cnblogs.com/w-y-1/p/5802089.html
Copyright © 2020-2023  润新知