题意:给定一个 n 个节点的有向无环图,再给出 m 个棋子,每一个棋子位于一个点上且互相不影响(即一个点上可以有多个棋子),每回合可以选择一个棋子按照给出的图把它移向下一个点,即当前点与下一个点间有一条有向边,由当前点指向下一个点,无法进行操作则判输,问先手是否必胜;
分析:一个棋子不能再移动当且仅当这个点的出度为0,因为每个棋子互不影响,所以分别求出每个棋子的SG函数,求一下异或和就好了;
代码:
#include<set>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int N = 1000+10;
vector<int>E[N];
int SG[N];
int dfs(int x){
if(SG[x]!=-1) return SG[x];
bool S[N]={0};
for(int i=0;i<E[x].size();i++){
//S.insert(dfs(E[x][i]));
S[dfs(E[x][i])]=1;
}
int res=0;
while(S[res]!=0) res++;
return SG[x]=res;
}
int main()
{
int n;
while(~scanf("%d",&n)){
for(int i=0,m,x;i<n;i++){
E[i].clear();
scanf("%d",&m);
while(m--){
scanf("%d",&x);
E[i].push_back(x);
}
}
memset(SG,-1,sizeof(SG));
int q,x;
while(~scanf("%d",&q)&&q){
int ans=0;
while(q--){
scanf("%d",&x);
ans^=dfs(x);
}
if(ans) puts("WIN");
else puts("LOSE");
}
}
}