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

 

 

你可能感兴趣的:(game)