1. 程式人生 > >CodeForces-937D-Sleepy Game

CodeForces-937D-Sleepy Game

som true sin size www problem mes space while

Sleepy Game 題意: 在一個無向圖中,找到一種策略,使得後手沒有路子可走;

思路(copy自劉哥blog):

dfs。

vis[u][0]==1表示u這個點能從s點偶數路徑到達

vis[u][1]==1表示u這個點能從s點奇數路徑到達

這個樣就能保證dfs時每個點最多被訪問2次

那麽如果存在一個點u,vis[u][1]==1且u的出度為0,那麽就存在能Win的方案

否則,dfs染色判環,如果存在從s點出發的環,就存在Draw的方案。註意這裏,只要有環就行,應為前面已經判斷過不會win

不然就是Lose

#include <cstdio>
#include <cstring>
#include 
<algorithm> #include <string> #include <iostream> #include <vector> using namespace std; const int maxn = 1e5+5; vector <int> mp[maxn],q; int pre[maxn][2]; int vis[maxn][2],vis2[maxn]; void dfs(int v,int s,int b) { if(vis[s][b]==1)return; vis[s][b] = 1; pre[s][b]
= v; for(int i=0; i<mp[s].size();i++) { dfs(s,mp[s][i],b^1); } } bool hasloop(int s) { vis2[s]=1; bool f = false; for(int i=0; i<mp[s].size(); i++) { int tmp = mp[s][i]; if(vis2[tmp]==1)return true; else f=hasloop(tmp); if(f)return
true; } vis2[s]=2; return false; } int main() { int n,m; scanf("%d%d",&n,&m); for(int i=1; i<=n; i++) { int c; scanf("%d",&c); while(c--) { int u; scanf("%d",&u); mp[i].push_back(u); } } int s; scanf("%d",&s); dfs(0,s,0); int u=0; for(int i=1;i<=n;i++) { if(vis[i][1]==1&&mp[i].size()==0) { u=i; break; } } if(u!=0) { printf("Win\n"); int b = 1; while(u != 0)  //這裏不要寫成u!=s,因為可能會再經過s; { //cout<<"#"<<pre[u][1]<<"-0-"<<pre[u][0]<<endl; q.push_back(u); u=pre[u][b]; b^=1; } //printf("%d",s); for(int i=q.size()-1;i>0;i--) printf("%d ",q[i]); printf("%d\n",q[0]); } else { if(hasloop(s)) { printf("Draw\n"); } else printf("Lose\n"); } return 0; }

CodeForces-937D-Sleepy Game