Codeforces Round #467 B - Sleepy Game
题目问题等同于找从s出发的路径,经过的点为偶数。是否存在这样的路径。
我们可以通过暴力dfs找到一条路径,深度为偶数。但是这里的问题在于,对于环该怎么处理。因为可能沿着环走一圈,可以改变一个点的深度的奇偶。
所以我们对于每一个点,针对奇偶进行判断。
这样的话,最多2*n个点,题目要求大于1e6输出draw,所以如果是dra'w的情况图中必然存在环。所以利用tarjan先判环即可。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<bitset>
#include<map>
//#include<regex>
#include<cstdio>
#include <iomanip>
#pragma GCC optimize(2)
#define up(i,a,b) for(int i=a;i<b;i++)
#define dw(i,a,b) for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
char ch = getchar(); ll x = 0, f = 1;
while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
const int N = 2e5 + 10;
struct eg {
int to, next;
}edge[2*N];
int head[2 * N];
int n, m, cnt;
bool flag = 0, flag2 = 0;
bool vis[N];
int pre[N];
int in[N];
int ans[5 * N];
int dfn[N], low[N];
stack<int>ST;
int st = 0;
int s;
void addedge(int u, int v)
{
edge[cnt].to = v;
edge[cnt].next = head[u];
head[u] = cnt++;
}
void dfs(int u,int d,int f)
{
vis[u] = 1;
dfn[u] = low[u] = ++st;
ST.push(u);
for (int i = head[u]; ~i; i = edge[i].next)
{
int v = edge[i].to;
if (!dfn[v]) {
dfs(v, d + 1, u); low[u] = min(low[u], low[v]);
}
else if (vis[v])
{
low[u] = min(low[u], dfn[v]);
}
if (flag2)return;
}
if (low[u] == dfn[u]) {
int t;
int cnt_ = 0;
do {
cnt_++;
t = ST.top();
ST.pop();
vis[t] = 0;
} while (t != u);
if (cnt_ != 1)flag2 = 1;
}
}
int dp[N][2];
int d_;
void dfs2(int u,int d,int f)
{
ans[d] = u;
pre[u] = f;
dp[u][d % 2] = 1;
int temp_cnt = 0;
for (int i = head[u]; ~i; i = edge[i].next)
{
temp_cnt++;
int v = edge[i].to;
if (dp[v][(d + 1) % 2])continue;
dfs2(v, d + 1, u);
if (flag)return;
}
if (temp_cnt == 0)
{
if (d % 2 == 0)
{
flag = 1;
d_ = d;
}
}
}
int main()
{
memset(head, -1, sizeof(head));
n = read(), m = read();
upd(i, 1, n)
{
int c, to;
c = read();
upd(j, 1, c)
{
to = read(); addedge(i, to);
in[to]++;
}
}
s = read();
dfs(s, 1, 0);
dfs2(s, 1, 0);
if (flag)
{
printf("Win\n");
upd(i, 1, d_)printf("%d ", ans[i]);
}
else {
if (flag2)printf("Draw");
else printf("Lose");
}
return 0;
}
橙橙橙