SG函数
将每个状态看成有向图中的一个点,这个点的SG函数值就是自然数中不属于(以这个点为起点的所有终点的SG函数值)这个集合的最小值,结束状态SG函数为0,该点无出边.
必胜状态
每个子游戏的起点的SG函数值异或和是整个游戏起点的SG函数值,SG函数为1先手必胜,SG函数值为0后手必胜.
如果整个游戏只有一个子游戏,不必求出每个点SG函数值的真实值,只需确定是否非0即可.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
vector<int>e;
int con=0;
vector<int>g[2048];
void add(int a,int b)
{
e.push_back(b);
g[a].push_back(con++);
}
int f[2048];
int dfs(int x)
{
if(f[x]>=0)
return f[x];
bool vis[2048];
memset(vis,0,sizeof(vis));
for(int i=0;i<g[x].size();++i)
{
vis[dfs(e[g[x][i]])]=1;
}
for(int i=0;i<2000;++i)
if(!vis[i])
{
f[x]=i;
break;
}
return f[x];
}
int main()
{
int n,m,k;cin>>n>>m>>k;
while(m--)
{
int a,b;cin>>a>>b;
add(a,b);
}
int ans=0;
memset(f,-1,sizeof(f));
while(k--)
{
int a;cin>>a;
ans^=dfs(a);
}
if(ans)
cout<<"win"<<endl;
else
cout<<"lose"<<endl;
return 0;
}