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 "); 73 else printf("Sally "); 74 } 75 return 0; 76 }