Codeforces 937D - Sleepy Game 【博弈+判环】


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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值