Read problem statements in [Mandarin], [Russian], and [Vietnamese] as well.

You are given a tree with N nodes rooted at node 1, and your task is to color each node of the tree either white or black. For each i (1 ≤ i ≤ N), let w_{i} be the number of white nodes that occurs in a simple path from the root node to i^{th} node and b_{i} be the number of black nodes that occurs in a simple path from the root node to i^{th} node. The cost of a node i is defined as the absolute difference between w_{i} and b_{i}. 

The cost of the tree is defined as the summation of the cost of all the nodes in the tree. The value of the tree is defined as the absolute difference between the total number of white nodes and the total number of black nodes in the tree. You have to color the tree in such a way that the cost of the tree is minimized.

Your task is to answer a single query Q, such that:

If Q = 1, Determine the maximum value the tree can have after minimizing the cost of the tree.
If Q = 2, Determine the minimum value the tree can have after minimizing the cost of the tree.

------ Input Format ------ 

- The first line contains an integer T, denoting the number of test cases. The T test cases then follow:
- The first line of each test case contains two integers N and Q, denoting the number of nodes in the tree and the query to answer respectively.
- The next N - 1 lines contain two space-separated integers u and v, denoting that there is an edge between the node u and the node v.

------ Output Format ------ 

For each test case, print a single line containing one integer - the answer to the query. 

------ Constraints ------ 

$1 ≤ T ≤ 1000$
$1 ≤ N ≤ 10^{5}$
$1 ≤ Q ≤ 2$
$1 ≤ u,v ≤ n, u \neq v$
$\sum{N}$ over all test cases does not exceed $10^{5}$.
- It is guaranteed that the given nodes and edges form a tree.

------ subtasks ------ 

Subtask #1 (20 points):
$Q = 1$

Subtask #2 (80 points):
Original constraints

----- Sample Input 1 ------ 
2
5 1
1 2
1 3
2 4
2 5
5 2
1 2
1 3
2 4
2 5

----- Sample Output 1 ------ 
3
1

----- explanation 1 ------ 
Test case 1: Color the node $1$ with black color and color the nodes $2, 3, 4, 5$ with white color to get the minimum cost of the tree, that is $3$, and the maximum value of the tree, that is $3$.

Test case 2: Color the nodes $1, 4$ with black color and color the nodes $2, 3, 5$ with white color to get the minimum cost of the tree, that is $3$, and the minimum value of the tree, that is $1$.

Source: codechef | Difficulty: VERY_HARD
Tags: Tree algorithms

Dynamic programming


Solutions:
from sys import stdin, setrecursionlimit
input = stdin.readline
setrecursionlimit(10 ** 6)

def dfs(p, prev, lvl):
	for i in child[p]:
		if i == prev:
			continue
		dfs(i, p, lvl + 1)
	if lvl & 1:
		a.append(abs(len(child[p]) - 2))

def answer():
	if q == 1:
		return sum(a)
	else:
		dp = 1
		for i in range(len(a)):
			dp |= dp << a[i]
		total = sum(a)
		ans = float('inf')
		for i in range(n + 1):
			if dp >> i & 1:
				ans = min(ans, abs(total - 2 * i))
		return ans
for T in range(int(input())):
	(n, q) = map(int, input().split())
	child = [[] for i in range(n + 1)]
	for i in range(n - 1):
		(u, v) = map(int, input().split())
		child[u].append(v)
		child[v].append(u)
	child[1].append(-1)
	a = []
	dfs(1, -1, 1)
	print(answer())


T = int(input())
for t in range(T):
	(N, Q) = [int(h) for h in input().split()]
	neb = [[] for n in range(N)]
	for n in range(N - 1):
		(u, v) = [int(h) for h in input().split()]
		neb[u - 1].append(v - 1)
		neb[v - 1].append(u - 1)
	depth = [0] * N
	depth[0] = 1
	queue = [0]
	idx = 0
	while idx < len(queue):
		parent = queue[idx]
		for child in neb[parent]:
			if depth[child] > 0:
				continue
			depth[child] = depth[parent] + 1
			queue.append(child)
		idx += 1
	nums = [len(neb[0]) - 1]
	for n in range(1, N):
		if depth[n] % 2 == 1:
			nums.append(abs(len(neb[n]) - 2))
	if Q == 1:
		print(sum(nums))
	else:
		nums.sort(reverse=True)
		if N > 500:
			s = 0
			for x in nums:
				s = min(s + x, abs(s - x))
			print(s)
			continue

		def sums(i, j):
			if j == i + 1:
				return [nums[i]]
			k = (i + j) // 2
			left = sums(i, k)
			right = sums(k, j)
			ret = set()
			for u in left:
				for v in right:
					ret.add(u + v)
					ret.add(abs(u - v))
			return list(ret)
		all_sums = sums(0, len(nums))
		print(min(all_sums))