D. Sleepy Game
time limit per test 2 seconds
memory limit per test 256 megabytes
Petya and Vasyaarranged a game. The game runs by the following rules. Players have a directedgraph consisting of n vertices and m edges. One of the vertices contains a chip. Initially the chip is locatedat vertex s. Players take turnsmoving the chip along some edge of the graph. Petya goes first. Player whocan't move the chip loses. If the game lasts for 106 turns the draw is announced.
Vasya wasperforming big laboratory work in "Spelling and parts of speech" atnight before the game, so he fell asleep at the very beginning of the game.Petya decided to take the advantage of this situation and make both Petya's andVasya's moves.
Your task is tohelp Petya find out if he can win the game or at least draw a tie.
Input
The first lineof input contain two integers n and m — the number of vertices and the number of edges in the graph (2 ≤ n ≤ 105, 0 ≤ m ≤ 2·105).
The next n lines contain the information about edges of the graph. i-th line (1 ≤ i ≤ n) contains nonnegative integer ci — number of vertices such that there is an edge from i to these vertices and ci distinct integers ai, j — indices of these vertices (1 ≤ ai, j ≤ n, ai, j ≠ i).
It is guaranteedthat the total sum of ci equals to m.
The next linecontains index of vertex s — theinitial position of the chip (1 ≤ s ≤ n).
Output
If Petya can winprint «Win» in the first line. In the next line print numbers v1, v2, ..., vk (1 ≤ k ≤ 106) — the sequence of vertices Petya should visit for the winning.Vertex v1 should coincide with s. For i = 1... k - 1 there should be an edge from vi to vi + 1 in the graph. There must be no possible move from vertex vk. The sequence should be such that Petya wins the game.
If Petya can't win but can draw a tie,print «Draw» in the only line. Otherwise print «Lose».
Examples
Input
Copy
5 6
2 2 3
2 4 5
1 4
1 5
0
1
Output
Win
1 2 4 5
Input
3 2
1 3
1 1
0
2
Output
Lose
Input
2 2
1 2
1 1
1
Output
Draw
Note
In the firstexample the graph is the following:
Initially thechip is located at vertex 1. In the firstmove Petya moves the chip to vertex 2, after that he moves it to vertex 4 for Vasya. After that he moves to vertex 5. Now it is Vasya's turn and there is no possible move, so Petya wins.
In the secondexample the graph is the following:
Initially thechip is located at vertex 2. The onlypossible Petya's move is to go to vertex 1. After that he has to go to 3 for Vasya. Now it's Petya's turn but he has no possible move, so Petyaloses.
In the thirdexample the graph is the following:
Petya can't win, but he can move alongthe cycle, so the players will draw a tie.
【题意】
给你一个有向图,两个人玩游戏,Petya先手,Vasya后手,每个人每次可以走一步,当一个人没路走的时候就输了,现在已知起点,而且Vasya睡着了,Petya帮她走,问游戏结果是Petya必胜还是平局,还是必败。
【思路】
显然,Petya必胜的条件是存在一条奇数长度的路径,且终点的出度为0.
否则只能是平局或必败,显然平局就是这个有向图里有环,剩下的便是必败。
我们考虑用DFS去判断路径的存在性。
dp[u][0]==1表示u这个点能从s点偶数长度路径到达
dp[u][1]==1表示u这个点能从s点奇数长度路径到达
DFS过程中记录一下前驱即可。
对于环的判断,我开始用了拓扑排序的方法,但是不知道为什么错了,后来才发现数据存在给出的图不连通的情况,这样就不能用拓扑排序了。
例:1->2 2->1 3孤立
于是还是利用DFS去判断,从起点开始,如果一个点被搜到了两次说明有环,但是还是会有问题,主要就是某个点可以通过多条不同路径到达一个点,这样虽然没有环但是会被认为有环,所以需要特殊标记(对应vis[now]=2)
例:1->2 1->3 2->4 3->4
#include <cstdio>
#include <cmath>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
#define mst(a,b) memset((a),(b),sizeof(a))
#define rush() int T;scanf("%d",&T);while(T--)
typedef long long ll;
const int maxn = 100005;
const ll mod = 1e9+7;
const int INF = 1e9;
const double eps = 1e-6;
int n,m;
int degree[maxn];
int vis[maxn];
int dp[maxn][2];
int pre[maxn][2];
vector<int>mp;
vector<int>vec[maxn];
void dfs(int now,int pp,int flag)
{
if(dp[now][flag]) return;
dp[now][flag]=1;
pre[now][flag]=pp;
for(int i=0;i<vec[now].size();i++)
{
dfs(vec[now][i],now,flag^1);
}
}
/*bool check()
{
int cnt=0;
queue<int>q;
for(int i=1;i<=n;i++) if(degree[i]==0) q.push(i);
while(q.size())
{
int u=q.front();
q.pop();
cnt++;
for(int i=0;i<vec[u].size();i++)
{
degree[vec[u][i]]--;
if(degree[vec[u][i]]==0) q.push(vec[u][i]);
}
}
return cnt==n;
}*/
bool check(int now)
{
vis[now]=1;
int flag=0;
for(int i=0;i<vec[now].size();i++)
{
int u=vec[now][i];
if(vis[u]==1) flag=1;
else if(vis[u]==0) flag=check(u);
if(flag) return 1;
}
vis[now]=2;
return 0;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
int k;
scanf("%d",&k);
for(int j=0;j<k;j++)
{
int x;
scanf("%d",&x);
vec[i].push_back(x);
degree[x]++;
}
}
int ss;
scanf("%d",&ss);
dfs(ss,0,0);
for(int i=1;i<=n;i++)
{
if(dp[i][1]&&vec[i].size()==0)
{
int tmp=i;
int flag=1;
mp.push_back(tmp);
while(pre[tmp][flag])
{
mp.push_back(pre[tmp][flag]);
tmp=pre[tmp][flag];
flag^=1;
}
puts("Win");
for(int j=mp.size()-1;j>=0;j--)
{
printf("%d ",mp[j]);
}
puts("");
return 0;
}
}
if(check(ss)) puts("Draw");
else puts("Lose");
}