给出一个有向无环图, 上面放有一些棋子, 两个人轮流移动棋子, 当一个人无法移动时, 算输。
求出每一个点的sg值, 异或就可以。出度为0的点sg值为0。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define pb(x) push_back(x) 4 #define ll long long 5 #define mk(x, y) make_pair(x, y) 6 #define lson l, m, rt<<1 7 #define mem(a) memset(a, 0, sizeof(a)) 8 #define rson m+1, r, rt<<1|1 9 #define mem1(a) memset(a, -1, sizeof(a)) 10 #define mem2(a) memset(a, 0x3f, sizeof(a)) 11 #define rep(i, a, n) for(int i = a; i<n; i++) 12 #define ull unsigned long long 13 typedef pair<int, int> pll; 14 const double PI = acos(-1.0); 15 const double eps = 1e-8; 16 const int mod = 1e9+7; 17 const int inf = 1061109567; 18 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; 19 const int maxn = 1e6+5; 20 int head[maxn], sg[1005], num; 21 struct node 22 { 23 int to, nextt; 24 }e[maxn]; 25 void init() { 26 mem1(head); 27 num = 0; 28 mem1(sg); 29 } 30 void add(int u, int v) { 31 e[num].to = v; 32 e[num].nextt = head[u]; 33 head[u] = num++; 34 } 35 int mex(int x) { 36 if(~sg[x]) 37 return sg[x]; 38 bool vis[1005]; 39 memset(vis, false, sizeof(vis)); 40 for(int i = head[x]; ~i; i = e[i].nextt) { 41 int v = e[i].to; 42 if(sg[v]==-1) 43 sg[v] = mex(v); 44 vis[sg[v]] = 1; 45 } 46 for(int i = 0; ; i++) 47 if(!vis[i]) 48 return i; 49 } 50 int main() 51 { 52 int n, x, y; 53 while(scanf("%d", &n)!=EOF) { 54 init(); 55 for(int i = 0; i<n; i++) { 56 scanf("%d", &x); 57 while(x--) { 58 scanf("%d", &y); 59 add(i, y); 60 } 61 } 62 while(scanf("%d", &x)&&x) { 63 int ans = 0; 64 for(int i = 0; i<x; i++) { 65 scanf("%d", &y); 66 ans ^= mex(y); 67 } 68 if(ans) { 69 puts("WIN"); 70 } else { 71 puts("LOSE"); 72 } 73 } 74 } 75 }