codeforces1249F. Maximum Weight Subset

https://codeforces.com/contest/1249/problem/F

F. Maximum Weight Subset

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

You are given a tree, which consists of nn vertices. Recall that a tree is a connected undirected graph without cycles.

Example of a tree.

Vertices are numbered from 11 to nn. All vertices have weights, the weight of the vertex vv is avav.

Recall that the distance between two vertices in the tree is the number of edges on a simple path between them.

Your task is to find the subset of vertices with the maximum total weight (the weight of the subset is the sum of weights of all vertices in it) such that there is no pair of vertices with the distance kk or less between them in this subset.

Input

The first line of the input contains two integers nn and kk (1≤n,k≤2001≤n,k≤200) — the number of vertices in the tree and the distance restriction, respectively.

The second line of the input contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤1051≤ai≤105), where aiai is the weight of the vertex ii.

The next n−1n−1 lines contain edges of the tree. Edge ii is denoted by two integers uiui and vivi — the labels of vertices it connects (1≤ui,vi≤n1≤ui,vi≤n, ui≠viui≠vi).

It is guaranteed that the given edges form a tree.

Output

Print one integer — the maximum total weight of the subset in which all pairs of vertices have distance more than kk.

Examples

input

Copy

5 1
1 2 3 4 5
1 2
2 3
3 4
3 5

output

Copy

11

input

Copy

7 2
2 1 2 1 2 1 1
6 4
1 5
3 1
2 3
7 5
7 4

output

Copy

4

dp要加一维来记录距离。参考 :https://codeforces.com/blog/entry/70822

import java.util.*;
import java.io.*;

public class Main {
	public static void main(String args[]) {new Main().run();}

	FastReader in = new FastReader();
	PrintWriter out = new PrintWriter(System.out);
	void run(){
		work();
		out.flush();
	}
	long mod=1000000007;
	long gcd(long a,long b) {
		return b==0?a:gcd(b,a%b);
	}
	int[] weight;
	ArrayList[] graph;
	int[][] dp;
	int k;
	void work() {
		int n=in.nextInt();
		k=in.nextInt();
		dp=new int[n][k+1];//节点node,距离最近的选择点距离至少为d时的 子树权值和的最大值
		weight=new int[n];
		for(int i=0;i[])new ArrayList[n];
		for(int i=0;i();
		}
		for(int i=0;i list=new ArrayList<>();
		for(int nn:graph[node]) {
			if(!vis[nn]) {
				dfs(nn,vis);
				list.add(nn);
			}
		}
		for(int i=0;i<=k;i++) {
			if(i==0) {
				dp[node][0]=weight[node];
				for(int nn:list) {
					dp[node][0]+=dp[nn][k];
				}
			}else{
				int v1=i-1;
				int v2=Math.max(v1,k-1-v1);
				int sum=0;
				int ret=0;
				for(int nn:list) {
					sum+=dp[nn][v2];
				}
				for(int nn:list) {
					sum-=dp[nn][v2];
					sum+=dp[nn][v1];//当v1点不选的情况肯定不是候选者
					ret=Math.max(ret, sum);
					sum+=dp[nn][v2];
					sum-=dp[nn][v1];
				}
				dp[node][i]=ret;
			}
		}
		for(int i=k-1;i>=0;i--) {
			dp[node][i]=Math.max(dp[node][i], dp[node][i+1]);
		}
	}
}



class FastReader
{
	BufferedReader br;
	StringTokenizer st;

	public FastReader()
	{
		br=new BufferedReader(new InputStreamReader(System.in));
	}

	public String next() 
	{
		if(st==null || !st.hasMoreElements())
		{
			try {
				st = new StringTokenizer(br.readLine());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return st.nextToken();
	}

	public int nextInt() 
	{
		return Integer.parseInt(next());
	}

	public long nextLong()
	{
		return Long.parseLong(next());
	}
}

 

你可能感兴趣的:(Codeforces)