poj 3710 Christmas Game 博弈论

思路:首先用Tarjan算法找出树中的环,环为奇数变为边,为偶数变为点。

之后用博弈论的知识:某点的SG值等于子节点+1后的异或和。

代码如下:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<vector>
 6 #include<cstring>
 7 using namespace std;
 8 int ans;
 9 vector<int>p[105];
10 bool vis[105],inss[105];
11 int low[105],dfa[105],num[105][105],ss[105],top;
12 void Tarjan(int u,int pre,int d)
13 {
14     low[u]=dfa[u]=d;
15     ss[top++]=u;
16     inss[u]=1;
17     for(int i=0;i<p[u].size();i++){
18         int v=p[u][i];
19         if(v==pre&&num[u][v]>1){
20             if(num[u][v]%2==0) vis[u]=1;
21             continue;
22         }
23         if(!dfa[v]){
24             Tarjan(v,u,d+1);
25             low[u]=min(low[u],low[v]);
26         }
27         else if(v!=pre&&inss[v]){
28             low[u]=min(low[u],dfa[v]);
29         }
30     }
31     if(low[u]==dfa[u]){
32         top--;
33         int cnt=1;
34         while(ss[top]!=u){
35             vis[ss[top--]]=1;
36             cnt++;
37         }
38         if(cnt&1) vis[ss[top+1]]=0;
39     }
40 }
41 int dfs(int d,int pre)
42 {
43     int ans=0;
44     for(int i=0;i<p[d].size();i++){
45         if(p[d][i]!=pre&&!vis[p[d][i]])
46             ans^=(1+dfs(p[d][i],d));
47     }
48     return ans;
49 }
50 int main()
51 {
52     int n,m,a,b,t,ans;
53     while(scanf("%d",&t)!=EOF){
54         ans=0;
55         while(t--){
56             memset(vis,0,sizeof(vis));
57             memset(ss,0,sizeof(ss));
58             memset(low,0,sizeof(low));
59             memset(dfa,0,sizeof(dfa));
60             memset(num,0,sizeof(num));
61             memset(inss,0,sizeof(inss));
62             scanf("%d%d",&n,&m);
63             for(int i=0;i<=n;i++) p[i].clear();
64             while(m--){
65                 scanf("%d%d",&a,&b);
66                 num[a][b]++;
67                 num[b][a]++;
68                 p[a].push_back(b);
69                 p[b].push_back(a);
70             }
71             top=0;
72             Tarjan(1,-1,1);
73             ans^=dfs(1,-1);
74         }
75         puts(ans?"Sally":"Harry");
76     }
77     return 0;
78 }
View Code

原文地址:https://www.cnblogs.com/xin-hua/p/3317973.html