poj 2425 A Chess Game (sg函数)

来源:互联网 发布:网络金融部工作怎么样 编辑:程序博客网 时间:2024/05/01 17:05

【题目大意】:给出一幅有向图,然后告诉你上面有m个棋子,游戏者轮流操作,走到不能走的人输。


【解题思路】:sg函数...棋子的每一次移动都是它的后继状态也就是 sg(x)=mex(SG[et[i].v])et[i].v为邻接表表示与其相连的点。

         每个棋子的移动视为一个子问题,将所有子问题^之后就是答案。


【代码】:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <queue>#include <cmath>#include <string>#include <cctype>#include <map>#include <iomanip>                   using namespace std;                   #define eps 1e-8#define pi acos(-1.0)#define inf 1<<30#define linf 1LL<<60#define pb push_back#define lc(x) (x << 1)#define rc(x) (x << 1 | 1)#define lowbit(x) (x & (-x))#define ll long longstruct Edge {    int u,v,next;} et[1000100];int eh[1100];int sg[1100];int n,m,tot,nn;inline void init(){    tot=0;    memset(eh,-1,sizeof(eh));}inline void addedge(int a,int b){    Edge e={a,b,eh[a]};    et[tot]=e;    eh[a]=tot++;}int solve_sg(int x){    if (sg[x]!=-1) return sg[x];    int vis[1100]={0};    for (int i=eh[x]; i!=-1; i=et[i].next){        int tmp;        tmp=solve_sg(et[i].v);        vis[tmp]=1;    }    int cnt=0;    while (vis[cnt]) cnt++;    sg[x]=cnt;    return cnt;}int main() {    while (~scanf("%d",&n)){        init();        for (int i=0; i<n; i++){            scanf("%d",&m);            int u;            for (int j=0; j<m; j++){                scanf("%d",&u);                addedge(i,u);            }        }        memset(sg,-1,sizeof(sg));                    while (~scanf("%d",&m)){            if (m==0) break;            int ans=0,tmp;            for (int i=0; i<m; i++){                scanf("%d",&tmp);                ans=ans^solve_sg(tmp);            }            if (ans==0) printf("LOSE\n");            else printf("WIN\n");        }    }    return 0;}