题目链接:uva 11927 - Games Are Important
题目大意:给出一张无环有向图,并给出每个节点上的石子数,每次操作可以选择一个石子,向下一个节点移动。两人轮流操作,直到不能操作为失败者。
解题思路:有了图之后,用记忆化的方式处理出每个节点的SG值,取所有石子数为奇数的节点的Nim和。
#include
#include
#include
using namespace std; const int maxn = 1005; int N, M, g[maxn][maxn], c[maxn], s[maxn]; inline int SG(int u) { if (s[u] != -1) return s[u]; int vis[maxn]; memset(vis, 0, sizeof(vis)); for (int i = 0; i < c[u]; i++) { int tmp = SG(g[u][i]); vis[tmp] = 1; } int ret = -1; while (vis[++ret]); return s[u] = ret; } void init () { int u, v; memset(s, -1, sizeof(s)); memset(c, 0, sizeof(c)); for (int i = 0; i < M; i++) { scanf("%d%d", &u, &v); g[u][c[u]++] = v; } for (int i = 0; i < N; i++) s[i] = SG(i); } int main () { while (scanf("%d%d", &N, &M) == 2 && N + M) { init(); int ans = 0, u; for (int i = 0; i < N; i++) { scanf("%d", &u); if (u&1) ans ^= s[i]; } printf("%s\n", ans ? "First" : "Second"); } return 0; }