Java教程

节点选择蓝桥杯Java

本文主要是介绍节点选择蓝桥杯Java,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

问题描述
有一棵 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.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class 节点选择 {
	// 邻接表
	static List<Integer>[] list;
	static int[][] dp;
	static int[] vaule;

	@SuppressWarnings({ "unchecked", "resource" })
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		// 存储权值
		dp = new int[n + 1][2];
		vaule = new int[n];
		for (int i = 0; i < n; i++) {
			vaule[i] = sc.nextInt();
		}
		// dp[i][j]表示i节点,如果j=0表示不选择该节点,j=1表示选择

		// 要最大值,那么dp[i][1]=dp[所有子节点][0]+value[i];
		// dp[i][0]=max(dp[所有子节点][0],dp[所有子节点][1]);
		// 添加数据进树
		list = new ArrayList[n];
		for (int i = 0; i < n; i++) {
			list[i] = new ArrayList<>();
		}
		// n-1次即可,list[]中第一个表示其父节点
		for (int i = 0; i < n - 1; i++) {
			int c = sc.nextInt();
			int d = sc.nextInt();
			// 下标减1,如输入1,2那么0(1-1)节点加上2,1(2-1)节点加上1
			list[c - 1].add(d - 1);
			list[d - 1].add(c - 1);
		}
		// 从根节点开始
		dfs(0, -1);
		System.out.print(Math.max(dp[0][0], dp[0][1]));
	}

// 搜索出最大的相加方法
	public static void dfs(int x, int y) {
		// 遍历这个节点下的子节点
		for (int i = 0; i < list[x].size(); i++) {
			// 获取子节点
			int num = list[x].get(i);
			// 不是父节点时
			if (num != y) {
				// 继续遍历x节点下的子节点
				dfs(num, x);
				// 分开2种情况
				dp[x][0] += Math.max(dp[num][0], dp[num][1]);
				// 这里不能加上自己的权值,因为还要判断上一个,只加上
				dp[x][1] += dp[num][0];
			}
		}
		// 遍历到最后的节点肯定是加上自己的值,再回上一层选择
		dp[x][1] += +vaule[x];

	}
}

这篇关于节点选择蓝桥杯Java的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!