蓝桥省赛 生命之树 深搜 树形DP

🍑 算法题解专栏


🍑 生命之树
在这里插入图片描述

输入

5
1 -2 -3 4 5
4 2
3 1
1 2
2 5

输出

8

🍑

import java.util.Arrays;
import java.util.Scanner;

public class 生命之树
{
	static int N = (int) 1e5 + 10;
	static int M = 2 * N, idx;

	static int[] w = new int[N];
	static int[] h = new int[N];
	static int[] ne = new int[M];
	static int[] e = new int[M];

	static long[] f = new long[N];//在以u为根的子树中包含u的所有连通块的权值的最大值

	public static void main(String[] args)
	{
		Arrays.fill(h, -1);// 头指针数组初始化
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		for (int i = 1; i <= n; i++)
			w[i] = sc.nextInt();

		for (int i = 0; i < n - 1; i++)
		{
			int a = sc.nextInt();
			int b = sc.nextInt();
			add(a, b);
			add(b, a);
		}
		dfs(1, -1);

		long res = f[1];
		for (int i = 2; i <= n; i++)
			res = Math.max(res, f[i]);
		if (res < 0)// 答案小于 0 时 不如不选
			res = 0;
		System.out.println(res);
	}

//	u 表示当前节点,p 表示父节点
	private static void dfs(int u, int p)
	{
		f[u] = w[u];
		for (int i = h[u]; i != -1; i = ne[i])
		{
			int t = e[i];
			if (t != p)// 避免走回头路(无向图)
			{
				dfs(t, u);// 递归搜索子树
				f[u] += Math.max(0, f[t]);
			}
		}
	}

//	添加一条 a 指向 b 的有向边
	private static void add(int a, int b)
	{
		e[idx] = b;
		ne[idx] = h[a];
		h[a] = idx++;
	}
}
posted @ 2023-04-26 11:44  兑生  阅读(21)  评论(0编辑  收藏  举报  来源
Live2D