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 }