Codeforces 937D dfs

D. Sleepy Game

题意:n 个点 , m 条边的有向图。有两个人 A 、B ,芯片开在点 s ,两人轮流移动芯片,A 为先手,最后不能移动者输。 但 B 在睡觉,所以 B 的移动由 A 帮他移。 问 A 是否能赢。如能,输出路径 ;如不能,输出是否可以 平局 或 输。
tags: 每个点两种状态 : 能到这个点且轮到 A 走,能到这个点且轮到B走。
用 pre[i][2] 表示这两种状态的前一个点,dfs 搜索状态,如果能到入度为 0 点,且轮到 B 走,那就赢了。如果不能赢就看是否有环。

//  937 D
#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi  first
#define se  second
typedef long long ll;
const int N = 200005;

bool flag, vis[N];
int n, m, out[N], pre[N][2];
vector< int > G[N];
void dfs(int u, int now)
{
    vis[u] = true;
    for(int to : G[u])
    {
        if(vis[to]) flag = true;
        if(pre[to][now^1]==0)
            pre[to][now^1]=u, dfs(to, now^1);
    }
    vis[u] = false;
}
stack< int > Stack;
void solve(int ed, int now) {
    Stack.push(ed);
    if(pre[ed][now]==INF) return ;
    solve(pre[ed][now], now^1);
}
void print_path(int ed) {
    puts("Win");
    solve(ed, 1);
    while(!Stack.empty()) {
        printf("%d ", Stack.top());
        Stack.pop();
    }
    puts("");
}
int main()
{
    scanf("%d%d", &n, &m);
    int ci, to;
    rep(i,1,n)
    {
        scanf("%d", &ci);
        rep(j,1,ci) {
            scanf("%d", &to);
            G[i].PB(to);
            ++out[i];
        }
    }
    int st;  scanf("%d", &st);
    pre[st][0] = INF;
    dfs(st, 0);
    rep(i,1,n)
        if(out[i]==0 && pre[i][1]) {
            print_path(i);  return 0;
        }
    puts(flag ? "Draw" : "Lose");

    return 0;
}
posted @ 2018-03-17 17:00  v9fly  阅读(119)  评论(0编辑  收藏  举报