1. 程式人生 > >Cut the tree _ HackerRank

Cut the tree _ HackerRank

有意思的題目,但是題目描述不正確(貌似阿三哥出的題目),讓我走了一些彎路,很tmd無語。。輸入嚴格來說根本不是樹,是圖來的,因為邊是無向邊。。但是它的輸入保證了是沒有環路的圖,所以某種程度上可以看做是樹(任何一個節點都可以為根節點,然後遞迴地把每個節點的鄰居看做子節點)。

不過話說回來如果一開始告訴我這個圖,我還真想不出來解法。。但是因為它“誤導”了我,讓我認為它是一顆樹後,問題就簡單了,每個樹節點遞迴地儲存它子樹的總和。然後深度遍歷即可。。

import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;

public class Solution {

	static int n;
	static int[] nodevals;
	static LinkedList<Integer>[] nodes;
	static int[] nodesum;
	static int root;
	static int minDif = Integer.MAX_VALUE;
	
	
    public static void main(String[] args) {
        /* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution. */
    	
    	Scanner scan = new Scanner(System.in);
    	n = scan.nextInt();
    	
    	nodevals = new int[n+1];
    	nodes = new LinkedList[n+1];
    	nodesum = new int[n+1];
    	
    	for(int i = 1;i<=n;i++)
    	{
    		nodevals[i] = scan.nextInt();
    		nodes[i] = new LinkedList<Integer>();
    	}
    	
    	for(int i = 1; i<n;i++)
    	{
    		int par = scan.nextInt();
    		int chd = scan.nextInt();
    		
    		nodes[par].addFirst(chd);
    		nodes[chd].addFirst(par);
    	}
    	

    	
    	depthSum(1,-1);
    	
    	depthMinDif(1,-1);
    	
    	System.out.println(minDif);
    }
    
    static int depthSum(int nodeInd,int par)
    {
    	nodesum[nodeInd] += nodevals[nodeInd];
    	
    	for(int chd : nodes[nodeInd]){
    		
    		if(chd == par)
    			continue;
    		
    		nodesum[nodeInd]+=depthSum(chd,nodeInd);
    	}
    	return nodesum[nodeInd] ;
    }
    
    static void depthMinDif(int nodeInd, int par){
    	int tmpdif = Math.abs(nodesum[1] - 2 * nodesum[nodeInd]);
    	if(tmpdif < minDif)
    		minDif = tmpdif;
    	
    	for(int chd : nodes[nodeInd]){
    		if(chd == par)
    			continue;
    		depthMinDif(chd,nodeInd);
    	}
    }
}