P11249 [GESP202409 七级] 小杨寻宝
题目
传送门
思路
借鉴了这道题洛谷题解区的第一篇题解
如何判断能否成功取得所有宝物?
我们观察样例的第二个测试数据,我们可以发现只要一个结点(不包括自身),周围如果有3个为1的结点,那么这个小杨一定不能取得宝物,我们把这个点叫做donk点(不幸点有点怪怪的QWQ)
如何找到donk点?
以x点为根,如果他的子树有3个包括为1的结点,那么我们就一定不能到达
But
我们以x为根节点,那么它上面的结点如何查找,我们可以判断以x为根节点的子树是否有全部的为1的结点,如果有,我们就按上面做就好了,如果没有,x的父亲结点发现一定有一个为1的结点,这是我们的条件变为了判断如果他的子树有2个为1的结点,那么我们就不能到达!
综上所述
如果我们以x为根节点的树的为1的结点的数量如果不等于我们全部为1的结点的数量,那么我们就判断它是否子树有3个包括为1的结点,否则就判断他的子树是否有2个为1的结点,只要满足任意一个,我们就一定不能到达!!!
代码
有注释
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,m;
bool f=0;
int a[N];
vector<int>v[N];
int dfs(int x,int fa){//目前结点和他的父节点
if(f==1)return 0;
if(v[x].size()==1&&fa==v[x][0]){//叶子结点直接返回
return a[x];
}
int ans1=0,ans2=0;//ans1是有1的子树数量,ans2是子树为1结点的总数量
for(int i=0;i<v[x].size();i++){
int u=v[x][i];
if(u!=fa){//不是父节点
int s=dfs(u,x);
if(f==1)return 0;//剪枝
if(s)ans1++;//如果有1
ans2+=s;
}
}
if(f==1)return 0;
ans2+=a[x];
if((ans2!=m&&ans1>=2)||ans1>=3){//看我的综上所述
f=1;//发现donk点
return 0;
}
return ans2;//返回子树包含的1的数量
}
int main(){
std::ios::sync_with_stdio(false);//关闭输入输出流
std::cin.tie(0);
std::cout.tie(0);
int t;
cin>>t;
while(t--){
cin>>n;
f=0;//初始化
m=0;//初始化
for(int i=1;i<=n;i++){
cin>>a[i];
m+=a[i];//求全部为一结点的数量
v[i].clear();//初始化
}
for(int i=1;i<n;i++){
int x,y;
cin>>x>>y;
v[x].push_back(y);
v[y].push_back(x);
}
dfs(1,0);//树的根节点可以随便取一个
if(!f){//如果没有donk点
cout<<"Yes";
}
else{//有donk点
cout<<"No";
}
cout<<'\n';
}
return 0;
}
无注释
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,m;
bool f=0;
int a[N];
vector<int>v[N];
int dfs(int x,int fa){
if(f==1)return 0;
if(v[x].size()==1&&fa==v[x][0]){
return a[x];
}
int ans1=0,ans2=0;
for(int i=0;i<v[x].size();i++){
int u=v[x][i];
if(u!=fa){
int s=dfs(u,x);
if(f==1)return 0;
if(s)ans1++;
ans2+=s;
}
}
if(f==1)return 0;
ans2+=a[x];
if((ans2!=m&&ans1>=2)||ans1>=3){
f=1;
return 0;
}
return ans2;
}
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int t;
cin>>t;
while(t--){
cin>>n;
f=0;
m=0;
for(int i=1;i<=n;i++){
cin>>a[i];
m+=a[i];
v[i].clear();
}
for(int i=1;i<n;i++){
int x,y;
cin>>x>>y;
v[x].push_back(y);
v[y].push_back(x);
}
dfs(1,0);
if(!f){
cout<<"Yes";
}
else{
cout<<"No";
}
cout<<'\n';
}
return 0;
}

浙公网安备 33010602011771号