1. 程式人生 > >藍橋杯-2015省賽-生命之樹

藍橋杯-2015省賽-生命之樹

在X森林裡,上帝建立了生命之樹。 他給每棵樹的每個節點(葉子也稱為一個節點)上,都標了一個整數,代表這個點的和諧值。 上帝要在這棵樹內選出一個非空節點集S,使得對於S中的任意兩個點a,b,都存在一個點列 {a, v1, v2, ..., vk, b} 使得這個點列中的每個點都是S裡面的元素,且序列中相鄰兩個點間有一條邊相連。 
在這個前提下,上帝要使得S中的點所對應的整數的和儘量大。 這個最大的和就是上帝給生命之樹的評分。  
經過atm的努力,他已經知道了上帝給每棵樹上每個節點上的整數。但是由於 atm 不擅長計算,他不知道怎樣有效的求評分。他需要你為他寫一個程式來計算一棵樹的分數。   


「輸入格式」 
第一行一個整數 n 表示這棵樹有 n 個節點。 第二行 n 個整數,依次表示每個節點的評分。 
接下來 n-1 行,每行 2 個整數 u, v,表示存在一條 u 到 v 的邊。由於這是一棵樹,所以是不存在環的。   
「輸出格式」 
輸出一行一個數,表示上帝給這棵樹的分數。   
「樣例輸入」 


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

import java.util.Scanner;
import java.util.Vector;

public class Main{
 
	/*
	 * 解題思路:每個頂點均有 選與不選 兩種情況
	 * node[i].dp[0]:不選
	 * node[i].dp[1]:選
	 * 狀態轉移方程:node[n].dp[1]+=Math.max(node[t].dp[1], node[t].dp[0]);
	 */
	static Node[] node;
	//定義結點
    static  class Node {
		int val;//頂點值
		boolean vis;//是否被訪問過,預設為false
		Vector<Integer> other=new Vector<Integer>();//鄰接點
		int[] dp=new int[2];//頂點 選與不選
	}
	
	//初始化
	public static void init(){
		Scanner in=new Scanner(System.in);
		int n=in.nextInt();
		node=new Node[n+1];
		for(int i=1;i<node.length;i++){//儲存頂點值
			node[i]=new Node();
			node[i].val=in.nextInt();
		}
		for(int i=0;i<n-1;i++){//儲存鄰接點
			int a=in.nextInt();
			int b=in.nextInt();
			node[a].other.add(b);
			node[b].other.add(a);
		}
	}
	
	public static void dfs(int n){
		node[n].dp[1]=node[n].val;
		node[n].dp[0]=0;
		node[n].vis=true;
		for(int i=0;i<node[n].other.size();i++){
			int t=node[n].other.get(i);
			if(!node[t].vis){
				dfs(t);
				node[n].dp[1]+=Math.max(node[t].dp[1], node[t].dp[0]);
			}else{
				node[n].dp[1]=Math.max(node[n].dp[1], node[n].val);
				node[n].dp[0]=Math.max(node[n].dp[0], 0);
			}
		}
		
	}
	public static int print(){
		int ans=-1;
		for(int i=1;i<node.length;i++){
			ans=Math.max(ans,node[i].dp[1]);
			ans=Math.max(ans,node[i].dp[0]);
		}
		return ans;
	}
	/*
     * 樹形dp
     */
	public static void main(String[] args) {
		init();
		dfs(1);
		System.out.println(print());		
	}
}


相關推薦

藍橋-2015-生命

在X森林裡,上帝建立了生命之樹。 他給每棵樹的每個節點(葉子也稱為一個節點)上,都標了一個整數,代表這個點的和諧值。 上帝要在這棵樹內選出一個非空節點集S,使得對於S中的任意兩個點a,b,都存在一個點列 {a, v1, v2, ..., vk, b} 使得這個點列中的每個

第六屆-藍橋-生命

10、生命之樹 在X森林裡,上帝建立了生命之樹。他給每棵樹的每個節點(葉子也稱為一個節點)上,都標了一個整數,代表這個點的和諧值。上帝要在這棵樹內選出一個非空節點集S,使得對於S中的任意兩個點a,b,都存在一個點列 {a, v1, v2, ..., vk, b} 使得這個點

藍橋-2016-Java -C組 第四題

骰子游戲 我們來玩一個遊戲。 同時擲出3個普通骰子(6個面上的數字分別是1~6)。 如果其中一個骰子上的數字等於另外兩個的和,你就贏了。 下面的程式計算出你能獲勝的精確概率(以既約分數表示) public class Main {     publi

藍橋-2016-Java -C組 第三題

平方怪圈 如果把一個正整數的每一位都平方後再求和,得到一個新的正整數。 對新產生的正整數再做同樣的處理。 如此一來,你會發現,不管開始取的是什麼數字, 最終如果不是落入1,就是落入同一個迴圈圈。 請寫出這個迴圈圈中最大的那個數字。 請填寫該最大數字。 注意:你提交的應該是一個整數

藍橋-2016-Java -C組 第二題

煤球數目 有一堆煤球,堆成三角稜錐形。具體: 第一層放1個, 第二層3個(排列成三角形), 第三層6個(排列成三角形), 第四層10個(排列成三角形), .... 如果一共有100層,共有多少個煤球? 請填表示煤球總數目的數字。 注意:你提交的應該是一個整數,不要填寫任何多餘的內容或說明

藍橋-2016-Java -C組 第一題

有獎猜謎 小明很喜歡猜謎語。 最近,他被邀請參加了X星球的猜謎活動。 每位選手開始的時候都被髮給777個電子幣。 規則是:猜對了,手裡的電子幣數目翻倍, 猜錯了,扣除555個電子幣, 扣完為止。 小明一共猜了15條謎語。 戰果為:vxvxvxvxvxvxvvx 其中v表示猜對了,x表

2017第八屆藍橋Java

第一題:購物單 小明剛剛找到工作,老闆人很好,只是老闆夫人很愛購物。老闆忙的時候經常讓小明幫忙到商場代為購物。小明很厭煩,但又不好推辭。 這不,XX大促銷又來了!老闆夫人開出了長長的購物單,都是有打折優惠的。  小明也有個怪癖,不到萬不得已,從不刷卡,直

2017第八屆藍橋Java有感

  相對於ACM程式設計大賽的難度,藍橋杯就算容易一些了,第八屆的難度比前兩屆也提高了不少,建議在HDOJ上多加練習,這樣就能輕鬆些。   從準備上講藍橋杯有很多題都有固定的套路,大量練習是必不可少的,校內選拔之後,就開始不斷的刷題總結的無限迴圈中。   臨

第六屆藍橋試題9】壘骰子 ( 矩陣快速冪 )

題目描述: 賭聖atm晚年迷戀上了壘骰子,就是把骰子一個壘在另一個上邊,不能歪歪扭扭,要壘成方柱體。  經過長期觀察,atm 發現了穩定骰子的奧祕:有些數字的面貼著會互相排斥! 我們先來規範一下骰子:

(第七屆藍橋個人賽)結果填空、程式碼填空

一、煤球數目(暴力解法,容易) 有一堆煤球,堆成三角稜錐形。具體: 第一層放1個, 第二層3個(排列成三角形), 第三層6個(排列成三角形), 第四層10個(排列成三角形), .... 如果一共有100層,共有多少個煤球? 請填表示煤球總數目的數字。 注

第六屆藍橋試題3】三羊獻瑞

題目描述: 觀察下面的加法算式:   其中,相同的漢字代表相同的數字,不同的漢字代表不同的數字。  請你填寫“三羊獻瑞”所代表的4位數字(答案唯一),不要填寫任何多餘內容。 題目答案: 1085 

第八屆藍橋試題5】取數位

題目描述: 求1個整數的第k位數字有很多種方法。 以下的方法就是一種。// 求x用10進製表示時的數位長度 int len(int x){ if(x<10) return 1; retur

第八屆藍橋試題2】等差素數列

題目描述: 2,3,5,7,11,13,....是素數序列。 類似:7,37,67,97,127,157 這樣完全由素陣列成的等差數列,叫等差素數數列。 上邊的數列公差為30,長度為6。 2004年,

第十屆藍橋C++A組(A題平方和)

std image code 判斷 省賽 條件 alt com == 只需要按照題目暴力算就完事了,最後結果是2658417853,代碼如下: #include <bits/stdc++.h> typedef long long ll; bool

2015藍橋B組第10題--生命

在X森林裡,上帝建立了生命之樹。 他給每棵樹的每個節點(葉子也稱為一個節點)上,都標了一個整數,代表這個點的和諧值。 上帝要在這棵樹內選出一個非空節點集S,使得對於S中的任意兩個點a,b,都存在一個點列 {a, v1, v2, ..., vk, b} 使得這個點列中的每個點都是S裡面的元素,且序列中相鄰兩個點

藍橋第六屆JAVA真題----生命

生命之樹 在X森林裡,上帝建立了生命之樹。  他給每棵樹的每個節點(葉子也稱為一個節點)上,都標了一個整數,代表這個點的和諧值。  上帝要在這棵樹內選出一個非空節點集S,使得對於S中的任意兩個點a,b,都存在一個點列 {a, v1, v2, …, vk, b} 使得

樹形dp|無根轉有根|2015藍橋生命

兩個 代碼 ima www. https 2015年 藍橋 ack 大小 2015年藍橋杯第十題——生命之樹(無根樹dfs) ①暴力解法:枚舉子集(選點) + dfs判斷連通性(題目要求連通)滿足上面兩個條件下找出最大值權值和 ②dfs無根樹轉有根樹,遞歸找最優 先學習

藍橋 生命

#include <cstdio> #include<iostream> #include <cstring> #include <cmath> #in

藍橋第六屆 第10題 生命

在X森林裡,上帝建立了生命之樹。 他給每棵樹的每個節點(葉子也稱為一個節點)上,都標了一個整數,代表這個點的和諧值。 上帝要在這棵樹內選出一個非空節點集S,使得對於S中的任意兩個點a,b,都存在一個

Internet of Lights and Switches 湖南2015 (字首異或和+map) (未完待續)

題面: You are a fan of “Internet of Things”(IoT, 物聯網), so you build a nice Internet of Lights and Switches in your huge mansion. Formally, there