洛谷 P11249 [GESP202409 七级] 小杨寻宝-普及/提高-
题目描述
小杨有一棵包含 nnn 个节点的树,树上的一些节点放置有宝物。
小杨可以任意选择一个节点作为起点并在树上移动,但是小杨只能经过每条边至多一次,当小杨经过一条边后,这条边就会消失。小杨每经过一个放置有宝物的节点就会取得该宝物。
小杨想请你帮他判断自己能否成功取得所有宝物。
输入格式
本题单个测试点内有多组测试数据。输入第一行包含一个正整数 ttt,代表测试用例组数。
接下来是 ttt 组测试用例。对于每组测试用例,一共 n+1n+1n+1 行。
第一行包含一个正整数 nnn,代表树的节点数。
第二行包含 nnn 个非负整数 a1,a2,…ana_1, a_2, \dots a_na1,a2,…an,其中如果 ai=1a_i = 1ai=1,则节点 iii 放置有宝物;若 ai=0a_i = 0ai=0,则节点 iii 没有宝物。
之后 n−1n - 1n−1 行,每行包含两个正整数 xi,yix_i, y_ixi,yi,代表存在一条连接节点 xix_ixi 和 yiy_iyi 的边。
输出格式
对于每组测试数据,如果小杨能成功取得所有宝物,输出 Yes,否则输出 No。
输入输出样例 #1
输入 #1
2
5
0 1 0 1 0
1 2
1 3
3 4
3 5
5
1 1 1 1 1
1 2
1 3
3 4
3 5
输出 #1
Yes
No
说明/提示
样例 1 解释
对于第一组测试用例,小杨从节点 222 出发,按照 2−1−3−42-1-3-42−1−3−4 的顺序即可成功取得所有宝物。
数据规模与约定
子任务编号 | 数据点占比 | ttt | nnn |
---|---|---|---|
111 | 20%20\%20% | ≤10\leq 10≤10 | ≤5\leq 5≤5 |
222 | 20%20\%20% | ≤10\leq 10≤10 | ≤103\leq 10^3≤103 |
333 | 60%60\%60% | ≤10\leq 10≤10 | ≤105\leq 10^5≤105 |
对全部的测试点,保证 1≤t≤101 \leq t \leq 101≤t≤10,1≤n≤1051 \leq n \leq 10^51≤n≤105,0≤ai≤10 \leq a_i \leq 10≤ai≤1,且保证树上至少有一个点放置有宝物。
solution
如果一个节点的有超过 2 颗子树有宝物,则不可以
如果有超过两个节点的有 2 颗子树有宝物也不可以
如果一个节点存在宝物,则其子节点中有 2 颗子树有宝物也不可以
代码
#include <iostream>
#include "bit"
#include "vector"
#include "unordered_set"
#include "set"
#include "queue"
#include "stack"
#include "algorithm"
#include "bitset"
#include "cstring"using namespace std;int n, t, a[100001], x, y;
vector<int> e[100001];
bool r, h;bool dfs(int u, int p) {int s = 0;for (int v: e[u]) {if (v != p) {s += dfs(v, u);}}if(a[u] && r) h = true;if (s >= 2) {if(!r) r = true;else h = true;}if(s >= 3) h = true;return s + a[u];
}int main() {cin >> t;while (t--) {r = h = false;cin >> n;for (int i = 1; i <= n; i++) {cin >> a[i];e[i].clear();}for (int i = 1; i < n; i++) {cin >> x >> y;e[x].push_back(y);e[y].push_back(x);}dfs(1, 0);cout << (h ? "No" : "Yes") << endl;}
}