题目链接:HDU 3590【PP and QQ】
思路
树上删边问题,套个反尼姆博弈。
反尼姆博弈是取走最后一个石子的人输掉游戏,所以需要特判一些特殊情况。
1. 有堆的石子个数都是1,所以堆数为奇数时,先手必败,否则先手必胜
2. 所有堆中存在石子数为非1的堆时,若所有堆的异或和为0则,先手必败,否则先手必胜。
克朗原理:对于树上的某一个点,它的分支可以转换为这个点为根的一根竹子,这个竹子的长度就是它各个分支的边的数量的异或和,异或和为0时,先手必胜,异或和为非0时,后手必胜。
代码
/*
n棵树的树上删边
*/
int sg[N], n, flag, t;
vector<int> edge[N];
void init() {
memset(sg, 0, sizeof sg);
for (int i = 0; i <= n; i++) {
edge[i].clear();
}
}
void dfsSG(int x, int fa) {
sg[x] = 0;
for (auto i : edge[x]) {
if (i == fa)
continue;
dfsSG(i, x);
sg[x] ^= (sg[i] + 1);
}
}
void solve() {
int res = 0;
flag = 0;
while (t--) {
n = read();
init();
for (int i = 1; i < n; i++) {
int u = read(), v = read();
edge[u].push_back(v);
edge[v].push_back(u);
}
dfsSG(1, 0);
if (sg[1] > 1)
flag = 1;
res ^= sg[1];
}
if ((res == 0 && flag == 0) || (res && flag)) {
cout << "PP" << endl;
} else {
cout << "QQ" << endl;
}
}
int main() {
while (~scanf("%d", &t)) {
solve();
}
return 0;
}
标签:QQ,HDU,3590,异或,必胜,flag,sg
From: https://www.cnblogs.com/againss/p/18363623