POJ2425 && HDU1524_ A Chess Game_树形博弈

/*
*State: Accepted    8104K    485MS    C++    1428B
*题目大意:
*        两个人在一个有向五环图上面走棋子,每次只能走一步,最后谁
*        没有棋子可走就败,然后棋子可以重叠,并且有n个棋子。要求判断
*        先手的胜负。
*解题思路:
*        一开始没有思路,后来试着用sg去推,推出sg了。
*解题感想:
*        用了静态邻接表之后,快了,但是此题不明显。
*        果然,静态邻接表的边的数目要把握好,RE了两次。
*/
View Code
 1 #include <iostream>
 2 #include <stdio.h>
 3 using namespace std;
 4 
 5 const int MAX = 1024;
 6 int sg[MAX], head[MAX], cnt;
 7 typedef struct node_
 8 {
 9     int v;
10     int next;
11 }N;
12 N edge[1000 * MAX];//注意边的数目
13 
14 void addEdge(int u, int v)
15 {
16     edge[cnt].v = v;
17     edge[cnt].next = head[u];
18     head[u] = cnt++;
19 }
20 
21 int get_sg(int n)
22 {
23     if(sg[n])
24         return sg[n];
25 
26     if(head[n] == -1)
27         return sg[n] = 0;
28 
29     int vst[MAX] = {0}, h = 0;
30     for(int f = head[n]; f != -1; f = edge[f].next)
31     {
32         int son = edge[f].v, tmp;
33         tmp = get_sg(son);
34         vst[tmp] = 1;
35     }
36     for(int i = 0; i < MAX; i++)
37     {
38         if(!vst[i])
39             return sg[n] = i;
40     }
41 }
42 
43 void init()
44 {
45     memset(head, -1, sizeof(head));
46     cnt = 0;
47 }
48 
49 int main(void)
50 {
51 #ifndef ONLINE_JUDGE
52     freopen("in.txt", "r", stdin);
53 #endif
54 
55     int n;
56     while(scanf("%d", &n) == 1)
57     {
58         init();
59         memset(sg, 0, sizeof(sg));
60         int in[MAX] = {0};
61         for(int i = 0; i < n; i++)
62         {
63             int m;
64             scanf("%d", &m);
65             for(int j = 0; j < m; j++)
66             {
67                 int t;
68                 scanf("%d", &t);
69                 addEdge(i, t);
70                 in[t]++;
71             }
72         }
73         for(int i = 0; i < n; i++)
74         {
75             if(!in[i])//入度为0的都要搜一遍
76                 get_sg(i);
77         }
78         int a;
79         while(scanf("%d", &a), a)
80         {
81             int yihuo = 0;
82             for(int i = 0; i < a; i++)
83             {
84                 int t;
85                 scanf("%d", &t);
86                 yihuo ^= sg[t];
87             }
88             if(!yihuo)
89                 printf("LOSE\n");
90             else
91                 printf("WIN\n");
92         }
93     }
94     return 0;
95 }
原文地址:https://www.cnblogs.com/cchun/p/2613139.html