Bakry and Partitioning

题目 C. Bakry and Partitioning

Bakry and Partitioning

Bakry faced a problem, but since he’s lazy to solve it, he asks for your help.
You are given a tree of n nodes, the i-th node has value ai assigned to it for each i from 1 to n. As a reminder, a tree on n nodes is a connected graph with n−1 edges.
You want to delete at least 1, but at most k−1 edges from the tree, so that the following condition would hold:
For every connected component calculate the bitwise XOR of the values of the nodes in it. Then, these values have to be the same for all connected components.
Is it possible to achieve this condition?

Input

Each test contains multiple test cases. The first line contains the number of test cases t (1≤t≤5⋅104). Description of the test cases follows.
The first line of each test case contains two integers n and k (2≤k≤n≤105).
The second line of each test case contains n integers a1,a2,…,an (1≤ai≤109).
The i-th of the next n−1 lines contains two integers ui and vi (1≤ui,vi≤n, ui≠vi), which means that there’s an edge between nodes ui and vi.
It is guaranteed that the given graph is a tree.
It is guaranteed that the sum of n over all test cases doesn’t exceed 2⋅105.

Output

For each test case, you should output a single string. If you can delete the edges according to the conditions written above, output “YES” (without quotes). Otherwise, output “NO” (without quotes).
You can print each letter of “YES” and “NO” in any case (upper or lower).

Example

input

5
2 2
1 3
1 2
5 5
3 3 3 3 3
1 2
2 3
1 4
4 5
5 2
1 7 2 3 5
1 2
2 3
1 4
4 5
5 3
1 6 4 1 2
1 2
2 3
1 4
4 5
3 3
1 7 4
1 2
2 3

output

NO
YES
NO
YES
NO

Note

It can be shown that the objection is not achievable for first, third, and fifth test cases.

In the second test case, you can just remove all the edges. There will be 5 connected components, each containing only one node with value 3, so the bitwise XORs will be 3 for all of them.

In the fourth test case, this is the tree:

在这里插入图片描述
You can remove an edge (4,5)

The bitwise XOR of the first component will be, a1⊕a2⊕a3⊕a4=1⊕6⊕4⊕1=2 (where ⊕ denotes the bitwise XOR).

The bitwise XOR of the second component will be, a5=2.

题意:
在至少一次,最多k-1次操作以内,是否能将当前树分为几个连通块,将这几个连通块内所有点的值进行异或,使得每个连通块的异或和相同。

思路:
可行方案分两种(即输出YES):
1.当前不进行操作时,所有值的异或和为0(此种任取一个数出来剩下的异或和都与此数相等,只需要一次操作,一定可行)。
2.所有值异或和不为0时,假设为x,则至少分成三个异或和为x的连通块(dfs搜索,异或和为x的连通块数量>=3并且k-1>=3即可)

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<math.h>
#include<vector>
#include<algorithm>
const int N=1e6+10;
using namespace std;
int t;
int n,k;
int a[N];//当前节点的值
int sum;//所有值异或和
int cnt;//连通块异或和为sum的数量
vector<int>g[N];

int dfs(int x,int p)
{
      int t=a[x];
      for(int i:g[x])
      {
          if(p!=i)t^=dfs(i,x);//当前i即g[x][i]
      }
//   上下两种写法相同
//    for(int i=0;i<g[x].size();i++)
//    {
//        if(p!=g[x][i])t^=dfs(g[x][i],x);
//    }
      if(t==sum){
         t=0;
         cnt++;
      }
      return t;
}
int main()
{
    cin>>t;
    while(t--)
    {
        cin>>n>>k;
        
        //初始化
        for(int i=0;i<=n;i++)
        g[i].clear();
        sum=0;
        cnt=0;
        
        for(int i=1;i<=n;i++){
                cin>>a[i];
                sum^=a[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,1);

        if((cnt>=3&&k>=3)||sum==0)cout<<"YES"<<endl;//可行的两种情况
        else cout<<"NO"<<endl;
    }
    return 0;
}

感谢浏览~

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值