Problem:
Score : 700 points

Problem Statement

There is a tree with N vertices, numbered 1 through N.
The i-th of the N-1 edges connects vertices a_i and b_i.

Currently, there are A_i stones placed on vertex i.
Determine whether it is possible to remove all the stones from the vertices by repeatedly performing the following operation:

Select a pair of different leaves. Then, remove exactly one stone from every vertex on the path between those two vertices.
Here, a leaf is a vertex of the tree whose degree is 1, and the selected leaves themselves are also considered as vertices on the path connecting them.

Note that the operation cannot be performed if there is a vertex with no stone on the path.

Constraints

2 ≦ N ≦ 10^5

1 ≦ a_i,b_i ≦ N

0 ≦ A_i ≦ 10^9

The given graph is a tree.

Input

The input is given from Standard Input in the following format:

N
A_1 A_2 … A_N
a_1 b_1
:
a_{N-1} b_{N-1}

Output

If it is possible to remove all the stones from the vertices, print YES. Otherwise, print NO.

Sample Input 1

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

Sample Output 1

YES

All the stones can be removed, as follows:

Select vertices 4 and 5. Then, there is one stone remaining on each vertex except 4.

Select vertices 1 and 5. Then, there is no stone on any vertex.

Sample Input 2

3
1 2 1
1 2
2 3

Sample Output 2

NO

Sample Input 3

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

Sample Output 3

YES

Solution in C (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <stdio.h>
#include <stdlib.h>

#define MAX 100000

int N;
int A[MAX];
int a[MAX], b[MAX];

int edge_num[MAX];
int* edges[MAX];
int* edges_work[MAX];

int main(void) {
	int i;
	/* 入力を読み込む */
	if (scanf("%d", &N) != 1) return 1;
	for (i = 0; i < N; i++) {
		if (scanf("%d", &A[i]) != 1) return 1;
	}
	for (i = 1; i < N; i++) {
		if (scanf("%d%d", &a[i], &b[i]) != 2) return 1;
		edge_num[a[i] - 1]++;
		edge_num[b[i] - 1]++;
	}
	/* 接続する辺の情報の領域を確保する */
	for (i = 0; i < N; i++) {
		edges_work[i] = edges[i] = malloc(sizeof(int) * edge_num[i]);
		if (edges[i] == NULL) return 2;
	}
	/* 接続する辺の情報を格納する */
	for (i = 1; i < N; i++) {
		*(edges_work[a[i] - 1]++) = b[i] - 1;
		*(edges_work[b[i] - 1]++) = a[i] - 1;
	}

	/* したの適当な条件(未証明)を各ノードについてチェック */
	for (i = 0; i < N; i++) {
		int j;
		if (edge_num[i] <= 2) {
			/* パイプ */
			for (j = 0; j < edge_num[i]; j++) {
				if ((edge_num[edges[i][j]] <= 2 && A[i] != A[edges[i][j]]) ||
				(edge_num[edges[i][j]] <= 2 && A[i] > A[edges[i][j]])) {
					puts("NO");
					return 0;
				}
			}
		} else {
			/* ハブ */
			long long sum = 0;
			for (j = 0; j < edge_num[i]; j++) {
				sum += A[edges[i][j]];
			}
			if (A[i] * 2LL > sum) {
				puts("NO");
				return 0;
			}
		}
	}

	puts("YES");
	return 0;
}

/*

例1

1[1]-3[1]-2[2]-4[1]
          |
          5[2]

例2

1[1]-2[2]-3[1]

例3

5[2]
|
1[3]-2[2]-3[2]
|
4[2]-6[2]

-------------------------------------

葉の場合
自分の通過回数 = 接続先の通過回数

葉以外の場合
自分の通過回数 = まわりの通過回数の合計 / 2

↑正しい操作なら満たすはず ←大ウソ！
  これを満たしているなら正しい操作が存在するか?

-------------------------------------

パイプ(次数が2以下)の場合
自分の通過回数 = 周りのパイプの通過回数(全部)

ハブ(次数が3以上)の場合
自分の通過回数 = まわりの通過回数の合計 / 2

↑少なくとも例では成立

-------------------------------------

↑WAを生やした→どういう場合に落ちるか？
切り捨てをチェックしてないのでダメ

4
1 1 1 1
1 2
1 3
1 4

3[1]
|
1[1]-2[1]
|
4[1]

-------------------------------------

↑WAを生やした→どういう場合に落ちるか？

     4[1]      7[1]
     |         |
6[1]-2[2]-1[1]-3[2]-8[1]
     |         |
     5[1]      9[1]

9
1 2 2 1 1 1 1 1 1
1 2
1 3
2 4
2 5
2 6
3 7
3 8
3 9

↑これは大丈夫

3[1] 5[1]
|    |
1[1]-2[1]
|    |
4[1] 6[1]

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

ポイント：まわりのノードから必ず来るわけではない

3[1] 5[1]
|    |
1[2]-2[2]
|    |
4[1] 6[1]

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

ポイント：まわりのノードから必ず来ないわけではない

3[2] 5[2]
|    |
1[4]-2[3]
|    |
4[3] 6[1]

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

ポイント：？？？？？

*/