POJ 2425

题意:给定一个有向无环图,然后上面的一些结点上面有棋子,每次一个人可以选择一枚棋子走到与它相邻的点,不能走的就输了。然后给出初态,判断胜负。

题解:图上面的SG博弈,dfs求SG函数,然后依次取异或就行了。

View Code
 1 #include<cstdio>

 2 #include<cstring>

 3 #include<algorithm>

 4 using namespace std;

 5 int sg[1005],head[1005],nc;

 6 struct Edge

 7 {

 8     int to,next;

 9 }edge[1000000];

10 void add(int a,int b)

11 {

12     edge[nc].to=b;edge[nc].next=head[a];head[a]=nc++;

13 }

14 bool vis[1005];

15 void dfs(int now)

16 {

17     vis[now]=true;

18     bool mark[1005];

19     memset(mark,false,sizeof(mark));

20     for(int i=head[now];i!=-1;i=edge[i].next)

21     {

22         int t=edge[i].to;

23         if(!vis[t])

24             dfs(t);

25         mark[sg[t]]=true;

26     }

27     for(int i=0;i<1005;i++)

28     {

29         if(!mark[i])

30         {

31             sg[now]=i;

32             break;

33         }

34     }

35 }

36 int main()

37 {

38     int n;

39     while(scanf("%d",&n)!=EOF)

40     {

41         memset(head,-1,sizeof(head));

42         nc=0;

43         for(int i=0;i<n;i++)

44         {

45             int nu;

46             scanf("%d",&nu);

47             for(int j=0;j<nu;j++)

48             {

49                 int t;

50                 scanf("%d",&t);

51                 add(i,t);

52             }

53         }

54         memset(vis,false,sizeof(vis));

55         for(int i=0;i<n;i++)

56         {

57             if(!vis[i])

58                 dfs(i);

59         }

60         int m;

61         while(scanf("%d",&m),m)

62         {

63             int ss=0;

64             for(int i=0;i<m;i++)

65             {

66                 int t;

67                 scanf("%d",&t);

68                 ss^=sg[t];

69             }

70             printf("%s\n",ss?"WIN":"LOSE");

71         }

72     }

73     return 0;

74 }

你可能感兴趣的:(poj)