题意: 给你一个树,之后有一些询问然后你可以在一些节点里放一枚棋子,每次可以往一个树枝边移动,谁不能移动谁输
思路: 就是我们需要打一个SG表,之后一个一次游戏的SG值是他子游戏的异或和就ok了
上代码把:
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn = 1e3+10;
vector<int>V[maxn];
int sg[maxn];
int dfs(int x){
if (sg[x]!=-1) return sg[x]; // 记忆化搜索
int mex[maxn];//注意这里的mex每次都有重新定义,因为他每进入一层深搜的话,那么就要一个新的mex
memset(mex,0,sizeof(mex));
for(int i=0;i<V[x].size();i++)
mex[dfs(V[x][i])]=1;//他的子游戏其实就是他的子节点
for(int i=0;;i++)
if (!mex[i]) return sg[x]=i;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int t,te;
for(int i = 0 ; i < n ; i++)
{
V[i].clear();
scanf("%d",&t);
while(t--)
{
scanf("%d",&te);
V[i].push_back(te);
}
}
memset(sg,-1,sizeof(sg));
while(scanf("%d",&te))
{
int ans = 0;
if(te == 0) break;
while(te--)
{
scanf("%d",&t);
ans = ans ^ dfs(t);//得到t的sg值
}
if(ans)
{
puts("WIN");
}
else puts("LOSE");
}
}
}