Node selection (tree dynamic programming)

Problem Description

There is a tree of n nodes, and each node in the tree has a positive integer weight. If a point is selected, none of its neighbors on the tree can be selected. What is the weight and maximum of the selected points?
input format

The first line contains an integer n.

The next line contains n positive integers, the ith positive integer representing the weight of point i.

There are n-1 lines in total, each describing an edge in the tree.
Output Format
Output an integer representing the maximum value of the weight sum of the selected points.
Sample input
5
1 2 3 4 5
1 2
1 3
2 4
2 5
Sample output
12 Sample
description Data size and convention

For 20% of the data, n <= 20.

For 50% of the data, n <= 1000.

For 100% of the data, n <= 100000.

The weights are all positive integers not exceeding 1000.

The idea of ​​​​solving
this problem is:
using the method of diffusion deep search , now traverse all nodes once, then backtrack , and record the sum of the weights (including its child nodes) taken or not taken by each node in turn, such as: take point i , then add and do not take the sum of the weights of the sub-byte; if not take the i point, compare the maximum value of the sum of the weights of the sub-node or not, and add the larger one. Go back all the way to the root node, and finally compare whether to take the root node or not, and display the final result.

code show as below:

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

/** 
 * @author 作者 : Cactus
 * @version 创建时间:2018-3-20 下午09:23:20 
 */
public class Main {
    private static int[][] arr_node = new int[100000][2];// 用于记录每个节点,选1或者不选0,其权值和(该节点和其所有子节点)
    private static int[][] arr_route = new int[100000][100];// 用于记录每个节点的孩子节点
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        //Arrays.fill(arr_node, 0);
        for(int i = 1; i <= n; i++){
            arr_node[i][1] = sc.nextInt();
        }
        //Arrays.fill(arr_route, 0);
        int start,end,j,k;
        for(int i = 0; i < n - 1; i++){
            start = sc.nextInt();
            end = sc.nextInt();
            j = 0;
            k = 0;
            while(arr_route[start][j] != 0){
                j++;
            }
            arr_route[start][j] = end;
            while(arr_route[end][k] != 0){
                k++;
            }
            arr_route[end][k] = start;

        }
        sc.close();
        //以上为存放相关数据
        dfs(1,0); //动态规划+深度搜索,从创建的数的根节点(即第1个顶点,0表示根节点的父母节点)开始进行DFS遍历
        System.out.println(fmax(arr_node[1][0],arr_node[1][1])); //比较第一个节点,选或不选哪个权值和更大,并输出
    }
    private static void dfs(int x, int f){
        int i,k;
        k = 0;
        while((i = arr_route[x][k]) != 0){ 
            k++;
            if(i != f){   //当前节点!=其父节点,防止出现start的孩子成为start的父亲情况
                dfs(i,x); //深搜
                arr_node[x][1] += arr_node[i][0]; //取x,则加上不取其子节点i的权值和
                arr_node[x][0] += fmax(arr_node[i][0],arr_node[i][1]);// 不取x,则选择取或不取其子节点i的权值和大者
                //状态转移方程
            }
        }
    }
    private static int fmax(int a, int b){
        return a > b ? a : b;
    }
}

The final test result is only 50 points, and the remaining five test cases are prompted to run errors, and the reason has not yet been found (it may be a timeout). But the C++ version is fully operational.
write picture description here

This code will be improved in the future. To speed up the speed of writing questions recently, I can only put it aside for a while.
Recently, I have involved a lot of algorithm problems, and it is very difficult to do. I also reminded myself from the side that my foundation is not solid enough, but I am also very happy. Although it is difficult to do, I can clearly feel my progress. come on!

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325518652&siteId=291194637