洛谷 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;
}
}
结果

更多推荐
所有评论(0)