cf1615D 树/异或/2200
D - X(or)-mas Tree
给定一个树,边权为-1表示未知。给定m个节点间路径异或和二进制1个数的奇偶性,判断能否构造一个合法的树满足条件
- 一个性质:设两个数为x,y。二进制下x有a个1,y有b个1。则:
- a ^ b = num_1(x ^ y) % 2
所以对于每个边权,我们只需要考虑其1的个数的奇偶性。把m条边加上后一起遍历判断,不确定的边利用异或的性质输出边权即可
注意这里用了内置的位运算函数,简单介绍一下
__builtin_ffs (unsigned int x)返回x的最后一位1的是从后向前第几位,比如7368(1110011001000)返回4
__builtin_clz (unsigned int x)返回前导的0的个数。
__builtin_ctz (unsigned int x) 返回后面的0个个数,和; builtin_clz相对。
__ builtin_popcount (unsigned int x) 返回二进制表示中1的个数。
__builtin_parity (unsigned int x) 返回x的奇偶校验位,也就是x的1的个数模2的结果。
#include <bits/stdc++.h>
#define ll long long
#define mp make_pair
#define fi first
#define se second
#define pb push_back
#define vi vector<int>
#define pi pair<int, int>
#define fr(a) freopen(a, "r", stdin)
#define fo(a) freopen(a, "w", stdout);
#define mod 998244353
template<typename T> bool chkmin(T &a, T b){return (b < a) ? a = b, 1 : 0;}
template<typename T> bool chkmax(T &a, T b){return (b > a) ? a = b, 1 : 0;}
ll ksm(ll a, ll b) {if (b == 0) return 1; ll ns = ksm(a, b >> 1); ns = ns * ns % mod; if (b & 1) ns = ns * a % mod; return ns;}
using namespace std;
const int maxn = 200005;
/**/
int t, n, m, err;
int dis[maxn], vis[maxn];
vector<pi>g[maxn];
/**/
void dfs(int u) {
if(err) return;
for(auto i:g[u]) {
int v = i.fi, w = i.se;
if(dis[v] == -1) {
dis[v] = dis[u] ^ w;
dfs(v);
}
else if(dis[v] != (dis[u] ^ w)) {
err = 1;
return;
}
}
}
void solve() {
err = 0;
vector< array<int, 3> >ed;
cin >> n >> m;
for(int i = 1; i <= n; i++) {
g[i].clear();
dis[i] = -1;
}
for(int i = 1; i < n; i++) {
int u, v, w;
cin >> u >> v >> w;
ed.pb({u, v, w});
if(w == -1) continue;
w = __builtin_parity(w);
g[u].pb({v, w});
g[v].pb({u, w});
}
for(int i = 1; i <= m; i++) {
int u, v, w;
cin >> u >> v >> w;
g[u].pb({v, w});
g[v].pb({u, w});
}
for(int i = 1; i <= n; i++) {
if(dis[i] == -1) dis[i] = 0, dfs(i);
}
if(err) {puts("NO"); return;}
puts("YES");
for(auto i: ed) {
int u = i[0], v = i[1], w = i[2];
if(w == -1) w = dis[u] ^ dis[v];
printf("%d %d %d\n", u, v, w);
}
}
int main()
{
// fr("test.in");
// fo("test.out");
ios::sync_with_stdio(0);cin.tie(0);
int T;
cin >> T;
while(T--) {
solve();
}
return 0;
}