POJ3710 Christmas Game 博弈论 sg函数 树的删边游戏

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

叶子节点的 SG 值为0;中间节点的SG值为它的所有子节点的SG值加1后的异或和。

偶环可以视作一个点,奇环视为一条边(连了两个点)。

这道题有两个需要注意的地方,这道题是多样例测试和这道题中两点之间形成的环要特判。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<iostream>
 6 #include<map>
 7 #include<ctime>
 8 using namespace std;
 9 const int maxn=1010;
10 int n;
11 struct nod{
12     int y,next;
13 }e[maxn*3];
14 int head[maxn]={},tot;
15 int dep[maxn]={},low[maxn]={},cnt;
16 int wtf[maxn][maxn]={};
17 int sta[maxn]={},top=0;
18 int f[maxn]={};
19 void init(int x,int y){
20     e[++tot].y=y;e[tot].next=head[x];head[x]=tot;
21 }
22 void dfs(int x,int fa){
23     int y;dep[x]=low[x]=++cnt;sta[++top]=x;
24     for(int i=head[x];i;i=e[i].next){
25         y=e[i].y;
26         if(y==fa){continue;}
27         if(wtf[x][y]!=1){continue;}
28         if(dep[y]){
29             low[x]=min(low[x],low[y]);
30         }else{
31             dfs(y,x);
32             low[x]=min(low[x],low[y]);
33         }
34     }
35     if(low[x]==dep[x]){
36         int z=0;
37         do{
38             z++;top--;
39         }while(sta[top+1]!=x);
40         if(z>2){
41             if(z&1){
42                 f[x]=1;
43             }
44         }
45         for(int i=head[x];i;i=e[i].next){
46             y=e[i].y;
47             if(y==fa){continue;}
48             if(wtf[x][y]!=1){continue;}
49             f[x]^=(f[y]+1);
50         }
51     }
52 }
53 int main(){
54     while(~scanf("%d",&n)){
55         int m,k;
56         int ans=0,x,y;
57         for(int i=1;i<=n;i++){
58             memset(head,0,sizeof(head));
59             memset(dep,0,sizeof(dep));
60             memset(low,0,sizeof(low));
61             memset(wtf,0,sizeof(wtf));
62             memset(f,0,sizeof(f));
63             tot=0;cnt=0;
64             scanf("%d%d",&m,&k);
65             for(int i=1;i<=k;i++){
66                 scanf("%d%d",&x,&y);
67                 init(x,y);init(y,x);
68                 wtf[x][y]++;wtf[y][x]++;
69             }dfs(1,0);
70             ans^=f[1];
71         }
72         if(!ans)printf("Harry\n");
73         else printf("Sally\n");
74     }
75     return 0;
76 }
View Code

 

posted @ 2018-01-20 16:18  鲸头鹳  阅读(136)  评论(0编辑  收藏  举报