Codeforces 937D - Sleepy Game
思路:
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的方案
不然就是Lose
代码:
#include<bits/stdc++.h> using namespace std; #define ll long long #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) const int N=1e5+5; vector<int>g[N],vc; int vis[N][2],pre[N][2],vs[N]; void dfs(int o,int u,int d){ if(vis[u][d]==1)return ; vis[u][d]=1; pre[u][d]=o; for(int i=0;i<g[u].size();i++){ dfs(u,g[u][i],d^1); } } bool hasloop(int u){ vs[u]=1; bool f=false; for(int i=0;i<g[u].size();i++){ if(vs[g[u][i]]==1)f=true; else if(vs[g[u][i]]==0)f=hasloop(g[u][i]); if(f)return true; } vs[u]=2; return false; } int main(){ ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n,m,t,u,s; cin>>n>>m; for(int i=1;i<=n;i++){ cin>>t; while(t--){ cin>>u; g[i].pb(u); } } cin>>s; dfs(0,s,0); for(int i=1;i<=n;i++){ if(vis[i][1]&&g[i].size()==0){ int u=i,t=1; vc.pb(u); while(pre[u][t]!=0){ vc.pb(pre[u][t]); u=pre[u][t]; t^=1; } cout<<"Win"<<endl; for(int j=vc.size()-1;j>=0;j--)cout<<vc[j]<<' '; cout<<endl; return 0; } } if(hasloop(s))cout<<"Draw"<<endl; else cout<<"Lose"<<endl; return 0; }