ALGO-4 结点选择

ALGO-4 结点选择

题目

资源限制

时间限制:1.0s 内存限制:256.0MB

问题描述

有一棵 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 的正整数。

题解

import java.io.*;
import java.util.*;

public class ALGO_4 {
    final static int MAX = 100010;
    int edgecount;
    int tree[] = new int[MAX];
    int dp[][] = new int[MAX][2];
    int visit[] = new int[MAX * 2];
    boolean visited[] = new boolean[MAX];

    class Edge {
        int start, end, next;

        Edge(int s, int e, int n) {
            start = s;
            end = e;
            next = n;
        }
    }

    Edge edge[] = new Edge[MAX * 2];

    void add(int start, int end) {
        edge[edgecount] = new Edge(start, end, tree[start]);
        tree[start] = edgecount++;
    }

    void dfs(int x, int x_father) {
        Arrays.fill(visited, false);
        int temp = 0;
        visited[x] = true;
        visit[temp++] = x;
        while (temp > 0) {
            x = visit[temp - 1];
            boolean edgevisited = false;
            for (int i = tree[x]; i + 1 != 0; i = edge[i].next) {
                int end = edge[i].end;
                if (visited[end])
                    continue;
                edgevisited = true;
                visit[temp++] = end;
                visited[end] = true;
            }
            if (edgevisited)
                continue;
            --temp;
            for (int i = tree[x]; i + 1 != 0; i = edge[i].next) {
                int x_son = edge[i].end;
                dp[x_son][0] += Math.max(dp[x][0], dp[x][1]);
                dp[x_son][1] += dp[x][0];

            }
        }
    }

    void run() throws IOException {
        int n = cin.nextInt();
        for (int i = 1; i <= n; ++i)
            dp[i][1] = cin.nextInt();
        Arrays.fill(tree, -1);
        for (int i = 1; i < n; ++i) {
            int x = cin.nextInt();
            int y = cin.nextInt();
            add(x, y);
            add(y, x);
        }
        dfs(1, 0);
        int ans = Math.max(dp[1][0], dp[1][1]);
        out.println(ans);
        out.close();
    }

    public static void main(String[] args) throws IOException {
        new ALGO_4().run();
    }

    ALGO_4() {
        cin = new InputReader(System.in);
        out = new PrintWriter(System.out);
    }

    InputReader cin;
    PrintWriter out;

    class InputReader {
        InputReader(InputStream in) {
            reader = new BufferedReader(new InputStreamReader(in));
            tokenizer = new StringTokenizer("");
        }

        private String next() throws IOException {
            while (!tokenizer.hasMoreTokens()) {
                tokenizer = new StringTokenizer(reader.readLine());
            }
            return tokenizer.nextToken();
        }

        public Integer nextInt() throws IOException {
            return Integer.parseInt(next());
        }

        private BufferedReader reader;
        private StringTokenizer tokenizer;
    }
}
posted @ 2022-03-18 13:19  morning-start  阅读(33)  评论(0编辑  收藏  举报