题意:
给一个拓扑图,在一些点上有棋子,两个玩家每次轮流将一颗棋子沿有向边移动一次,无法移动则失败。
分析:
理解nim和状态的grundy值两下就敲出来了。
代码:
//poj 2425 //sep9 #include <iostream> #include <vector> using namespace std; const int maxN=1024; vector<int> g[maxN]; int vis[maxN]; int grundy[maxN]; int dfs(int u) { if(grundy[u]!=-1) return grundy[u]; int val[1024]; memset(val,0,sizeof(val)); for(int i=g[u].size()-1;i>=0;--i) val[dfs(g[u][i])]=1; int i; for(i=0;;++i) if(val[i]==0) break; return grundy[u]=i; } int main() { int n; while(scanf("%d",&n)==1){ memset(vis,0,sizeof(vis)); memset(grundy,-1,sizeof(grundy)); for(int i=0;i<n;++i){ g[i].clear(); int num; scanf("%d",&num); while(num--){ int x; scanf("%d",&x); g[i].push_back(x); vis[x]=1; } } for(int i=0;i<n;++i) if(vis[i]==0) dfs(i); int q; while(scanf("%d",&q)&&q){ int ans=0; while(q--){ int x; scanf("%d",&x); ans=ans^grundy[x]; } if(ans) puts("WIN"); else puts("LOSE"); } } return 0; }
原文地址:http://blog.csdn.net/sepnine/article/details/45204991