1. 程式人生 > >B. Sleepy Game 博弈搜索

B. Sleepy Game 博弈搜索

spa body 不能 std 16px clas ces for .com

題意:給一個有向圖和起點,然後只有一名選手,這名選手可以隨意挪動棋子,最終不能動的時候走過的邊為奇數邊為Win並輸出路徑,否則如果有環輸出Draw,否則輸出Lose;

題目鏈接

知道狀態數最多只有n*2就可以了,分成先後手考慮。

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=2e5+88;
int vis[N][2],top,nxt[N],n,m,x,y,p,to[N],H[N],tot;
bool cir; int nt[N][2]; bool dp[N][2]; void add(int u,int v){ ++tot;nxt[tot]=H[u];to[tot]=v;H[u]=tot; } void dfs(int now,int k){ bool ko=0; if(vis[now][k]==-1) return; vis[now][k]=1; for(int i=H[now];i;i=nxt[i]){ int v=to[i]; ko=1; if((vis[v][k^1
]==1)|(vis[v][k]==1)) cir=1; if(vis[v][k^1]==1) continue; dfs(v,k^1); if(!k) { if(!dp[v][k^1]) dp[now][k]=1,nt[now][k]=v; } else { if(dp[v][k^1]) dp[now][k]=0,nt[now][k]=v; } } if(!ko) dp[now][k]=0; vis[now][k]
=-1; } void print(int p,int k){ if(!p) {puts("");return;} printf("%d ",p),print(nt[p][k],k^1); } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) dp[i][1]=1; for(int i=1;i<=n;++i) { scanf("%d",&x); while(x--) { scanf("%d",&y); add(i,y); } } scanf("%d",&p); dfs(p,0); if(dp[p][0]) puts("Win"),print(p,0); else if(cir) puts("Draw"); else puts("Lose"); }

B. Sleepy Game 博弈搜索