题目链接:点击这里
一个情况下的状态只和连接根的1的边数量有关。直接树上维护边。
#include <bits/stdc++.h>
using namespace std;
#define maxn 40005
long long n, m;
struct node {
int v, next, w;
}edge[maxn<<1];
int head[maxn], cnt;
int scan () {
char ch=' ';
while(ch<'0'||ch>'9')ch=getchar();
int x=0;
while(ch<='9'&&ch>='0')x=x*10+ch-'0',ch=getchar();
return x;
}
void add_edge (int u, int v, int w) {
edge[cnt].v = v, edge[cnt].w = w, edge[cnt].next = head[u]; head[u] = cnt++;
}
int fa[maxn], num[maxn], e[maxn], deep[maxn];
void dfs (int u, int father, int d) {
deep[u] = d;
fa[u] = father;
for (int i = head[u]; i != -1; i = edge[i].next) {
int v = edge[i].v; if (v == father) continue;
e[v] = i;
dfs (v, u, d+1);
}
}
int main () {
//freopen ("more.in", "r", stdin);
int t; scanf ("%d", &t);
while (t--) {
scanf ("%lld%lld", &n, &m);
memset (head, -1, sizeof head);
cnt = 0;
for (int i = 1; i < n; i++) {
int u, v, w; u = scan (), v = scan (), w = scan ();
add_edge (u, v, w);
add_edge (v, u, w);
}
dfs (1, 0, 1);
for (int i = 1; i <= m; i++) {
int op = scan ();
if (op == 1) {
int u = scan (), v = scan (), w = scan ();
while (u != v) {
if (deep[u] < deep[v]) swap (u, v);
int id = e[u];
edge[id].w = edge[id^1].w = w;
u = fa[u];
}
}
else {
int u = scan ();
int ans = 0;
for (int i = head[u]; i != -1; i = edge[i].next) {
ans += edge[i].w;
}
if (ans&1) printf ("Girls win!\n");
else printf ("Boys win!\n");
}
}
}
return 0;
}