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;
}
posted @ 2020-03-30 19:25  LORDXX  阅读(86)  评论(0编辑  收藏  举报