POJ - 2425 A Chess Game (树形博弈)

题意: 给你一个树,之后有一些询问然后你可以在一些节点里放一枚棋子,每次可以往一个树枝边移动,谁不能移动谁输

思路: 就是我们需要打一个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");
		}
	}
	
}

猜你喜欢

转载自blog.csdn.net/wjmwsgj/article/details/80196758