time limit per test
2 seconds
memory limit per test
256 megabytes
Kid was gifted a tree of nn vertices with the root in the vertex 11. Since he really like symmetrical objects, Kid wants to find out if this tree is symmetrical.
For example, the trees in the picture above are symmetrical.
And the trees in this picture are not symmetrical.
Formally, a tree is symmetrical if there exists an order of children such that:
- The subtree of the leftmost child of the root is a mirror image of the subtree of the rightmost child;
- the subtree of the second-left child of the root is a mirror image of the subtree of the second-right child of the root;
- ...
- if the number of children of the root is odd, then the subtree of the middle child should be symmetrical.
Input
The first line of input data contains single integer tt (1≤t≤1041≤t≤104) — the number of test cases in the test.
The first line of each case contains an integer nn (1≤n≤2⋅1051≤n≤2⋅105) — the number of vertices in the tree.
The following n−1n−1 lines contain two integers each uu and vv (1≤u,v≤n1≤u,v≤n, u≠vu≠v) — indices of vertices connected by an edge.
It is guaranteed that the sum of nn over all cases does not exceed 2⋅1052⋅105.
Output
Output tt strings, each of which is the answer to the corresponding test case. As an answer, output "YES" if this tree is symmetrical, and "NO" otherwise.
You can output the answer in any case (for example, the strings "yEs", "yes", "Yes" and "YES" will be recognized as a positive answer).
Example
Input
Copy
6
6
1 5
1 6
1 2
2 3
2 4
7
1 5
1 3
3 6
1 4
4 7
4 2
9
1 2
2 4
2 3
3 5
1 7
7 6
7 8
8 9
10
2 9
9 10
2 3
6 7
4 3
1 2
3 8
2 5
6 5
10
3 2
8 10
9 7
4 2
8 2
2 1
4 5
6 5
5 7
1
Output
Copy
YES NO YES NO NO YES 每次测试的时间限制为2秒 每次测试的内存限制256 MB 孩子被赠予一棵n树 根位于顶点1的顶点 因为他真的很喜欢对称的物体,Kid想知道这棵树是否是对称的。 例如,上图中的树木是对称的。 这张照片中的树木不是对称的。 从形式上讲,如果存在如下子级顺序,则树是对称的: 根的最左侧子树的子树是最右侧子树子树的镜像; 所述根的第二左子树的子树是所述根第二右子树的小树的镜像; ... 如果根的子节点数量是奇数,那么中间子节点的子树应该是对称的。 输入 第一行输入数据包含单个整数t (1≤t≤104 )--测试中的测试用例数。 每个案例的第一行包含一个整数n (1≤n≤2⋅105 )--树中的顶点数。 以下n−1 每行包含两个整数u 和v (1≤u,v≤n u≠v )--由边连接的顶点的索引。 保证n的和 在所有情况下不超过2⋅105 . 输出 输出t 字符串,每个字符串都是相应测试用例的答案。作为答案,如果此树是对称的,则输出“是”,否则输出“否”。 您可以在任何情况下输出答案(例如,字符串“yEs”、“yEs”、“yEs”和“yEs”将被识别为肯定答案)。 例子 输入复制 6. 6. 1 5 1 6 1 2 2 3 2 4 7. 1 5 1 3 3 6 1 4 4 7 4 2 9 1 2 2 4 2 3 3 5 1 7 7 6 7 8 8 9 10 2 9 9 10 2 3 6 7 4 3 1 2 3 8 2 5 6 5 10 3 2 8 10 9 7 4 2 8 2 2 1 4 5 6 5 5 7 1. 输出复制 对 不 对 不 不 对 代码:
#include <iostream>
#include <vector>
#include <map>
#include <random>
#include <utility>
#include <sstream>
using namespace std;
const int MAXN = 2e5 + 10;
const int MOD[2] = { 1145141, 998244353 };
mt19937 rd(time(0));
int C1[2], C2[2];
vector<long long> E[MAXN];
pair<long long, long long> Hash(pair<long long, long long> c) {
return make_pair(
(c.first * C1[0] % MOD[0] + (c.first ^ C1[0]) % MOD[0]) % MOD[0],
(c.second * C1[1] % MOD[1] + (c.second ^ C1[1]) % MOD[1]) % MOD[1]
);
}
pair<long long, long long> dp[MAXN];
vector<pair<long long, long long>> son[MAXN];
void dfs(long long u, long long fa) {
dp[u] = make_pair(114, 514);
for (long long v : E[u]) {
if (v == fa) continue;
dfs(v, u);
pair<long long, long long> s = Hash(dp[v]);
dp[u] = make_pair(
(dp[u].first + s.first) % MOD[0],
(dp[u].second + s.second) % MOD[1]
);
son[u].push_back(dp[v]);
}
}
bool solve(long long u, long long fa) {
if (son[u].size() == 0) return true;
map<pair<long long, long long>, int> mp;
for (auto now : son[u]) {
mp[now] ^= 1;
}
vector<pair<long long, long long>> vec;
for (auto now : son[u]) {
if (mp[now] == 1) {
vec.push_back(now);
mp[now] ^= 1;
}
}
if (vec.size() == 1) {
for (long long v : E[u]) {
if (v != fa && dp[v] == vec[0]) {
return solve(v, u);
}
}
}
else if (vec.size() >= 2) return false;
return true;
}
void work(stringstream& ss) {
long long n;
cin >> n;
for (long long i = 1; i < n; i++) {
long long u, v;
cin >> u >> v;
E[u].push_back(v);
E[v].push_back(u);
}
dfs(1, 0);
ss << (solve(1, 0) ? "YES\n" : "NO\n");
for (long long i = 1; i <= n; i++) {
dp[i] = make_pair(0, 0);
E[i].clear();
son[i].clear();
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
C1[0] = rd() % MOD[0];
C1[1] = rd() % MOD[1];
C2[0] = rd() % MOD[0];
C2[1] = rd() % MOD[1];
long long t;
cin >> t;
stringstream ss;
while (t--) work(ss);
cout << ss.str();
return 0;
}