测评会员优惠活动进行中 · 开通 VIP,有效期内测评不限次 VIP 优惠中 · 测评不限次 立即查看

A30335. 小杨寻宝

填空题 困难

题目描述

小杨寻宝

题目描述

小杨有一棵包含 n 个节点的树,树上的一些节点放置有宝物。

小杨可以任意选择一个节点作为起点并在树上移动,但是小杨只能经过每条边至多一次,当小杨经过一条边后,这条边就会消失。小杨每经过一个放置有宝物的节点就会取得该宝物。

小杨想请你帮他判断自己能否成功取得所有宝物。

输入格式

第一行包含一个正整数 t,代表测试用例组数。

接下来是t组测试用例。对于每组测试用例,一共n+1行。

第一行包含一个正整数 n,代表树的节点数。

第二行包含n个非负整数 a1,a2,,,,an,其中如果 ai =1,则节点 放置有宝物,若 ,ai =0,则节点 i 没有宝物。

之后 n-1 行,每行包含两个正整数 xi ,yi ,代表存在一条连接节点 xi 和 yi 的边。

输出格式

对于每组测试数据,如果小杨能成功取得所有宝物,输出 Yes,否则输出 No。

输入样例

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

输出样例

Yes
No

参考答案

#include<bits/stdc++.h> using namespace std; const int N = 1e5+10; vector<int> g[N]; int col[N],dep[N],has[N]; void dfs(int x,int fa) { dep[x]=dep[fa]+1; for (auto i:g[x]) { if(i!=fa) { dfs(i,x); } } } bool dfs2(int x,int fa) { for (auto i:g[x]) { if(i!=fa) { auto res = dfs2(i,x); if(res==false)return false; if(has[i]||col[i])has[x]++; } } if(has[x]>1)return false; return true; } int main() { int t; cin>>t; while(t--) { int n; cin>>n; for (int i=1;i<=n;i++) { dep[i]=0; g[i].clear(); cin>>col[i]; } for (int i=1;i<n;i++) { int u,v; cin>>u>>v; g[u].push_back(v); g[v].push_back(u); } dfs(1,0); int mx=0,pos=0; for (int i=1;i<=n;i++) { has[i]=0; if(col[i]) { if(dep[i]>mx) { mx=dep[i]; pos=i; } } } bool res= dfs2(pos,0); if(res)cout<<"Yes\n"; else cout<<"No\n"; } }
上一题 下一题