1. 程式人生 > >Codeforces 937D dfs

Codeforces 937D dfs

put pre long 狀態 -s inf 題意 esp 表示

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;
}

Codeforces 937D dfs