【每日蓝桥】33、一五年省赛Java组真题“生命之树”

你好呀,我是灰小猿,一个超会写bug的程序猿!

欢迎大家关注我的专栏“每日蓝桥”,该专栏的主要作用是和大家分享近几年蓝桥杯省赛及决赛等真题,解析其中存在的算法思想、数据结构等内容,帮助大家学习到更多的知识和技术!

标题:生命之树

在X森林里,上帝创建了生命之树.

他给每棵树的每个节点(叶子也称为-一个节点)上, 都标了一个整数,代表这个点的和谐值.

上帝要在这棵树内选出一个非空节点集S,使得对于S中的任意两个点a,b,都存在一个点

列{a,vl,v2.... vk, b}使得这个点列中的每个点都是S里面的元素,且序列中相邻两个点间有一条边相连.

在这个前提下,上帝要使得S中的点所对应的整数的和尽量大.

这个最大的和就是上帝给生命之树的评分.

经过atm的努力,他已经知道了上帝给每棵树上每个节点上的整数.但是由于atm不擅长

计算,他不知道怎样有效的求评分.他需要你为他写一个程序来计算一棵树的分数.

【输人格式】

第一行一个整数n表示这棵树有n个节点.

第二行n个整数,依次表示每个节点的评分.

接下来n-1行,每行2个整数u,v,表示存在一条u到v的边.由于这是一棵树,所以

是不存在环的.

【输出格式】

输出一行一个数,表示上帝给这棵树的分数.

 

【样例输入】

5

1 -2 -3 4 5

4 2

3 1

1 2

2 5

【样例输出】

8

【数据范围】

对于30%的数据,n<=10

对于100%的数据,0<n<=10^5 每个节点的评分的绝对值不超过10^6

【资源约定】

峰值内存消耗(含虚拟机)< 256M

CPU消耗 < 3000ms

请严格按要求输出,不要画蛇添足的打印类似“请您输入...”的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。

注意:不要使用package语句,不要使用jdk1.6及以上的版本特性

注意:主类的名称必须是Main 否则按无效代码处理。

解题思路:

本题在求解过程中需要了解树的深度遍历过程,其实本题考察的也就是数的遍历,以题中的例子为例,解法如下:

答案源码:

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Year2015_Bt10 {

	static int n;	//树的节点数
	static int MaxN = 100000;	//最大的权值
	static int [] w = new int[MaxN+1];	//存放每一个节点的权值
	static int [] ww = new int[MaxN+1];	//记录每个节点的总体权重
	static List<Integer> [] g;	//记录两节点之间的路径
	static int ans;
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		n = scanner.nextInt();
		for (int i = 1; i <= n; i++) {
			w[i] = scanner.nextInt();
		}
		g = new ArrayList[n+1];
		initG();//初始化记录路径的g列表
		//利用列表来记录每两个点之间的路径关系
		for (int i = 1; i <= n-1 ; i++) {
			int u = scanner.nextInt();
			int v = scanner.nextInt();
			g[u].add(v);
			g[v].add(u);
		}
		ans = 0;
		dfs(1,0);//令第一个节点是根节点,它的父亲节点是0
		System.out.println(ans);
	}
	
	//对树进行深度遍历
	private static void dfs(int root, int fg) {
		ww[root] = w[root];
		for (int i = 0; i < g[root].size(); i++) {
			int son = g[root].get(i);	//获取到root节点的儿子节点
			//如果获取到的节点不是root节点的父亲节点
			if (son!=fg) {
				dfs(son, root);//让儿子节点作为根节点,root节点作为它的父节点继续遍历
				if (ww[son]>0) {//如果该节点的权重大于0,则他的父节点的权重就加上它的权重
					ww[root]+=ww[son];
				}
			}
		}
		
		if (ww[root]>ans) {
			ans = ww[root];
		}
		
	}

	//初始化g列表
	private static void initG() {
		for (int i = 1; i < g.length; i++) {
			g[i] = new ArrayList<Integer>();
		}
	}

}

输出样例:

其中有不足或者改进的地方,还希望小伙伴留言提出,一起学习!

感兴趣的小伙伴可以关注专栏!

灰小猿陪你一起进步!

猜你喜欢

转载自blog.csdn.net/weixin_44985880/article/details/114984649