POJ 2425 A Chess Game 博弈论 sg函数

http://poj.org/problem?id=2425

典型的sg函数,建图搜sg函数预处理之后直接求每次游戏的异或和。仍然是因为看不懂题目卡了好久。

这道题大概有两个坑,

1.是搜索的时候vis数组应该在函数内声明(似乎这是我经常在搜索里犯的错误,为了省一点空间整道题都写错了);

2.是n个点的有向无环图边数上限是n^2(re了好久QAQ)。

在漫长的查资料过程之后终于大概搞懂了sg函数的原理,愉快。下一篇大概会写一个小结。

代码

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<iostream>
 6 #include<map>
 7 using namespace std;
 8 const int maxn=1010;
 9 int n,m;
10 struct nod{
11     int y,next;
12 }e[maxn*maxn];
13 int head[maxn]={},tot=0;
14 int f[maxn]={};
15 void dfs(int x){
16     if(f[x]!=-1)return;
17     if(head[x]==0){
18         f[x]=0;return;
19     }
20     bool vis[maxn]={};
21     for(int i=head[x];i;i=e[i].next){
22         dfs(e[i].y);
23         vis[f[e[i].y]]=1;
24     }
25     for(int i=0;i<=n;i++){
26         if(!vis[i]){
27             f[x]=i;break;
28         }
29     }
30 }
31 int main(){
32     while(~scanf("%d",&n)){
33         int x,y;
34         memset(head,0,sizeof(head));
35         memset(f,-1,sizeof(f));
36         tot=0;
37         for(int i=1;i<=n;i++){
38             scanf("%d",&x);
39             for(int j=1;j<=x;j++){
40                 scanf("%d",&y);
41                 e[++tot].y=y+1;
42                 e[tot].next=head[i];
43                 head[i]=tot;
44             }    
45         }
46         for(int i=1;i<=n;i++){
47             if(f[i]==-1)dfs(i);
48         }
49         while(~scanf("%d",&m)){
50             if(m==0)break;
51             y=0;
52             for(int i=1;i<=m;i++){
53                 scanf("%d",&x);
54                 y^=f[x+1];
55             }
56             if(y){
57                 printf("WIN\n");
58             }
59             else{
60                 printf("LOSE\n");
61             }
62         }
63     }
64     return 0;
65 }
View Code

 

posted @ 2017-12-22 17:15  鲸头鹳  阅读(158)  评论(0编辑  收藏  举报