题意:
有多颗树,然后树上删边游戏,最后一个删的人输。
思路:
其实就是树上删边游戏和anti-sg结合嘛。
对于树上删边:
1. 叶子节点的sg为0
2. 中间节点的sg为所有儿子节点的sg+1的异或和
对于anti-sg:先手必胜态当且仅当
1. sg异或值不为0且某个单一游戏的sg>1
2. sg异或为0且不存在sg>1的单一游戏
组合起来就好了。
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
std::vector<int> g[N];
int dfs(int u,int p){
int ans=0;
for (int i=0;i<g[u].size();i++){
int k=g[u][i];
if (k!=p){
ans^=(dfs(k,u)+1);
}
}
return ans;
}
int main(int argc, char const *argv[])
{
int T,n;
while (~scanf("%d",&T)){
int ans=0,cnt=0;
while (T--){
scanf("%d",&n);
for (int i=0;i<=n;i++) g[i].clear();
for (int i=1;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
g[u].push_back(v);
g[v].push_back(u);
}
int k=dfs(1,-1);
if (k>1) cnt++;
ans^=k;
}
if ((ans&&cnt)||(!ans&&!cnt)) puts("PP");
else puts("QQ");
}
return 0;
}