题目链接
题目思路
这个题目的思路还是没有那么的难
首先如果要分成偶数个块,那么这个树的总异或和一定要为0,并且如果总异或和为0,那么必定可以分为两个联
通块,如果分为奇数个的话,那么就看是否可以分为3个即可,就是先删除一个深度最大的联通块的异或和为总异
或和,然后再dfs判断是否还有另外一个,没想到居然就是两次dfs的事情就行了,主要是没想到先删除
代码
#include<bits/stdc++.h>
#define pii pair<int,int>
#define fi first
#define se second
#define debug cout<<"I AM HERE"<<endl;
using namespace std;
typedef long long ll;
const int maxn=1e5+5,inf=(1ll<<31)-1,mod=1e9+7;
const double eps=1e-6;
int n,k;
vector<int> g[maxn];
int dp[maxn];
int a[maxn];
int dep[maxn];
bool vis[maxn];
void dfs(int u,int fa){
dp[u]=a[u];
dep[u]=dep[fa]+1;
for(auto x:g[u]){
if(x==fa) continue;
if(vis[x]) continue;
dfs(x,u);
dp[u]^=dp[x];
}
}
signed main(){
int _;scanf("%d",&_);
while(_--){
scanf("%d%d",&n,&k);
int sum=0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
sum^=a[i];
dep[i]=0;
g[i].clear();
}
for(int i=1,u,v;i<=n-1;i++){
scanf("%d%d",&u,&v);
g[u].push_back(v);
g[v].push_back(u);
}
dfs(1,1);
bool flag=0;
int ma=-1,id=-1;
for(int i=2;i<=n;i++){
if(dp[i]==sum&&dep[i]>ma){
id=i;
ma=dep[i];
}
}
if(dp[1]==0){
flag=1;
}else{
if(id!=-1&&k>=3){
for(int i=1;i<=n;i++){
dp[i]=0;
}
vis[id]=1;
dfs(1,1);
for(int i=2;i<=n;i++){
if(dp[i]==sum){
flag=1;
break;
}
if(i==n){
flag=0;
}
}
vis[id]=0;
}
}
printf(flag?"YES
":"NO
");
}
return 0;
}