Roughly speaking, this problem asks you to create the checker of [*the problem used in December CookOff*].

You are given a tree with N vertices and a string C of length N, consisting of the characters 'R', 'G' and 'B'.

For each integer i\ (1≤ i≤ N), C_{i} is the color of vertex i — 'R' is for Red, 'G' is for Green and 'B' is for Blue.

The input is called valid if for all pairs of Blue vertices (u,\ v),\ u\neq v, there is at least one Red vertex and one Green vertex on the [simple path] between u and v.

Your task is to validate the input for given T test cases. For each test case, print Yes if the input is valid, otherwise No.

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

- The first line of input contains one positive integer T, the number of test cases. The description of T test cases follows.
- The first line of each test case contains one positive integer N, the number of vertices of the tree.
- The second line of each test case contains a string C, denoting the colors of the vertices.
- Each of the following N - 1 lines contains two space-separated integers u and v, denoting an edge between vertices u and v in the tree.

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

For each test case, output a single line containing Yes if the input is valid, and No otherwise.

You may print each character of the string in uppercase or lowercase (for example, the strings "yEs", "yes", "Yes" and "YES" will all be treated as identical).

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

$1 ≤ T ≤ 10^{4} $
$1 ≤ N ≤ 2\cdot 10^{5}$
- The sum of $N$ for each test case is at most $2\cdot 10^{5}$
$|C|=N$
$C$ consists of three types of characters, 'R', 'G' and 'B'
$1 ≤ u, v ≤ N, u \neq v$
- The input graph forms a tree

----- Sample Input 1 ------ 
5
4
BRGB
3 2
1 2
4 3
3
RGB
1 2
2 3
1
B
2
BB
1 2
4
BRGB
3 2
1 2
4 2
----- Sample Output 1 ------ 
Yes
Yes
Yes
No
No
----- explanation 1 ------ 
- Test case 1:
- The only pair is $(1, 4)$.
- Test case 3:
- There are no pairs.
- Test case 5:
- The only pair is $(1, 4)$. There are no Green vertices on the path between $1$ and $4$.

Source: codechef | Difficulty: VERY_HARD
Tags: Tree algorithms

Graph algorithms

Data structures

Graph traversal


Solutions:
import sys
sys.setrecursionlimit(10 ** 6)
input = sys.stdin.readline
for t in range(int(input())):
	n = int(input())
	s = input()
	graph = [[] for _ in range(n + 1)]
	for _ in range(n - 1):
		(u, v) = map(int, input().split())
		if s[u - 1] == 'R' and s[v - 1] == 'G' or (s[u - 1] == 'G' and s[v - 1] == 'R'):
			continue
		graph[u].append(v)
		graph[v].append(u)
	visit = set()

	def dfs(u, count):
		visit.add(u)
		if s[u - 1] == 'B':
			count[0] += 1
		if count[0] > 1:
			return False
		for v in graph[u]:
			if v not in visit:
				if not dfs(v, count):
					return False
		return True
	flag = False
	for i in range(1, n + 1):
		if i not in visit:
			if not dfs(i, [0]):
				flag = True
				break
	if flag:
		print('No')
	else:
		print('Yes')


import math, sys
input = sys.stdin.readline
S = lambda : input().rstrip()
I = lambda : int(S())
M = lambda : map(int, S().split())
L = lambda : list(M())
mod1 = 1000000007
mod2 = 998244353
from collections import deque
for _ in range(I()):
	n = I()
	c = S()
	adj = [[] for i in range(n)]
	f = 1
	v = [0] * n
	for i in range(n - 1):
		(a, b) = M()
		a -= 1
		b -= 1
		if c[a] == 'R' and c[b] == 'G' or (c[a] == 'G' and c[b] == 'R'):
			continue
		adj[a].append(b)
		adj[b].append(a)

	def bfs(i):
		q = deque()
		b = 0
		q.append(i)
		v[i] = 1
		b += c[i] == 'B'
		while q:
			r = q.popleft()
			for j in adj[r]:
				if v[j] == 0:
					b += c[j] == 'B'
					q.append(j)
					v[j] = 1
		return b
	for i in range(n):
		if v[i] == 0:
			b = bfs(i)
			if b > 1:
				f = 0
				break
	print('Yes' if f else 'No')


import sys
int1 = lambda x: int(x) - 1
pDB = lambda *x: print(*x, end='\n', file=sys.stderr)
p2D = lambda x: print(*x, sep='\n', end='\n\n', file=sys.stderr)

def II():
	return int(sys.stdin.readline())

def LI():
	return list(map(int, sys.stdin.readline().split()))

def LLI(rows_number):
	return [LI() for _ in range(rows_number)]

def LI1():
	return list(map(int1, sys.stdin.readline().split()))

def LLI1(rows_number):
	return [LI1() for _ in range(rows_number)]

def SI():
	return sys.stdin.readline().rstrip()
dij = [(0, 1), (-1, 0), (0, -1), (1, 0)]
inf = 18446744073709551615
md = 10 ** 9 + 7

def solve():
	n = II()
	cc = SI()
	to = [[] for _ in range(n)]
	for _ in range(n - 1):
		(u, v) = LI1()
		to[u].append(v)
		to[v].append(u)
	root = 0
	e = lambda : [inf, inf]

	def op(a, b):
		return [min(a[0], b[0]), min(a[1], b[1])]

	def trans_up(u):
		if cc[u] == 'B':
			dp[u] = [0, 0]
		if dp[u][0] == inf:
			return
		if cc[u] == 'R':
			dp[u][0] = 1
		if cc[u] == 'G':
			dp[u][1] = 1
		return

	def trans_down(u):
		p = par[u]
		if cc[p] == 'B':
			rdp[u] = [0, 0]
		if cc[p] == 'R':
			rdp[u][0] = 1
		if cc[p] == 'G':
			rdp[u][1] = 1
		return
	uu = []
	stack = [root]
	par = [-1] * n
	while stack:
		u = stack.pop()
		uu.append(u)
		vv = []
		for v in to[u]:
			if v == par[u]:
				continue
			vv.append(v)
			par[v] = u
			stack.append(v)
		to[u] = vv
	dp = [e() for _ in range(n)]
	rdp = [e() for _ in range(n)]
	for u in uu[::-1]:
		p = par[u]
		if p != -1:
			trans_up(u)
			dp[p] = op(dp[p], dp[u])
	for u in uu:
		cs = e()
		for v in to[u]:
			rdp[v] = cs
			cs = op(cs, dp[v])
		cs = op(e(), rdp[u])
		for v in to[u][::-1]:
			rdp[v] = op(rdp[v], cs)
			trans_down(v)
			cs = op(cs, dp[v])
		dp[u] = cs
	for u in range(n):
		if cc[u] == 'B' and min(dp[u]) == 0:
			print('No')
			return
	print('Yes')
for _ in range(II()):
	solve()


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

def dfs(p, prev):
	count = 0
	for i in child[p]:
		if i == prev:
			continue
		count += dfs(i, p)
	return count + (a[p - 1] == 'B')

def answer():
	for i in range(1, n + 1):
		count = dfs(i, -1)
		if count > 1:
			return 'No'
	return 'Yes'
for T in range(int(input())):
	n = int(input())
	a = input().strip()
	child = [[] for i in range(n + 1)]
	for i in range(n - 1):
		(u, v) = map(int, input().split())
		if a[u - 1] == 'R' and a[v - 1] == 'G':
			continue
		if a[u - 1] == 'G' and a[v - 1] == 'R':
			continue
		child[u].append(v)
		child[v].append(u)
	print(answer())