1. 程式人生 > >POJ 2425 A Chess Game 博弈論 sg函數

POJ 2425 A Chess Game 博弈論 sg函數

數組 scanf 博弈 break struct itl clu using b-

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

POJ 2425 A Chess Game 博弈論 sg函數