Codeforces 937D

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;
}
原文地址:https://www.cnblogs.com/widsom/p/8491394.html