题目链接:http://codeforces.com/contest/937/problem/D

D. Sleepy Game
time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Petya and Vasya arranged a game. The game runs by the following rules. Players have a directed graph consisting of n vertices and medges. One of the vertices contains a chip. Initially the chip is located at vertex s. Players take turns moving the chip along some edge of the graph. Petya goes first. Player who can't move the chip loses. If the game lasts for 106 turns the draw is announced.

Vasya was performing big laboratory work in "Spelling and parts of speech" at night 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 and Vasya's moves.

Your task is to help Petya find out if he can win the game or at least draw a tie.

Input

The first line of 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 ≤ nai, j ≠ i).

It is guaranteed that the total sum of ci equals to m.

The next line contains index of vertex s — the initial position of the chip (1 ≤ s ≤ n).

Output

If Petya can win print «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

Copy

3 2
1 3
1 1
0
2

output
Lose

input

Copy

2 2
1 2
1 1
1

output
Draw

分析:

好久不做题,手都生了。这道题是一道有向图的题。题意简单来说就是,给你一张有向图(不保证图连通,因为m可以等于0),首先问你从一个特定的点出发能不能走入一个环,然后问你从特定的点出发,能不能走到一个出度为0的点,使得这个出度为0的点距出发点距离为奇数(因为先手替后手走,所以只要存在一个就赢了)。

首先说怎么判断第一个问题:如果是问你一个有向图中是否有一个环,那么直接用拓扑排序就可以了。可是如果从一个特定的点出发,就要考虑dfs。一个点的状态有三种,vis=1(这个点所有的儿子已经遍历完),vis=-1(这个点没有被遍历过),vis=0(这个点已经被遍历过,但是他的儿子没有被遍历完),这样,当你扩展一个节点时,如果走到了一个vis=0的节点,那就说明这个点一定是从子孙节点又遍历回去了,所以就有了一个环。

对于第二个问题就比较简单了,开一个二维数组dp[maxn][2],dp[x][0]代表如果存在一条路径,使得出发节点st到x的长度为偶数,那么dp[x][0]就是x节点的上一个节点。同理,dp[x][1]代表如果存在一条路径,使得出发节点st到x的长度为奇数,那么dp[x][1]就是x节点的上一个节点。也就是说dp[now][0]可以去更新dp[next][1],dp[now][1]可以更新dp[next][0],而且不必要重复更新。这样一来,复杂度最多为O(2*n)。

代码:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
const int maxn=1e5+10;
vector<int>p[maxn];
int dp[maxn][2],path[maxn];
int vis[maxn];
int type,ans;
bool hasDraw;
void init()
{
    for(int i=0;i<maxn;i++)
        p[i].clear();
    memset(dp,-1,sizeof(dp));
    memset(vis,-1,sizeof(vis));
    hasDraw=0;
    type=0;
    ans=-1;
}
void dfs(int now)//dfs遍历是否有环
{
    if(hasDraw)
        return;
    for(int i=0;i<p[now].size();i++)
    {
       int next=p[now][i];
       if(vis[next]==-1)//next没有被遍历过
       {
           vis[next]=0;
           dfs(next);
       }
       else if(vis[next]==0)//next的儿子节点没有遍历完,则一定是从儿子节点回去的
       {
           hasDraw=1;
            return;
       }
       else if(vis[next]==1)
        continue;
    }
    //遍历完,vis置为1
    vis[now]=1;
    return;
}

void findans(int now)
{
    int e=p[now].size();
    if((e==0)&&(dp[now][1]!=-1))
    {
        ans=now;
        return ;
    }
    for(int i=0;i<p[now].size();i++)
    {
        int next=p[now][i];
        if((dp[now][0]!=-1)&&(dp[next][1]==-1))//可更新
        {
            dp[next][1]=now;
            findans(next);
        }
        if((dp[now][1]!=-1)&&(dp[next][0]==-1))
        {
            dp[next][0]=now;
            findans(next);
        }
    }

return ;
}
int main()
{
    int n,m,num,a,st,en;
    cin>>n>>m;
    init();
    for(int i=1;i<=n;i++)
    {
        cin>>num;
        while(num--)
        {
            cin>>a;
            p[i].push_back(a);
        }
    }
    cin>>st;
    vis[st]=0;
    dfs(st);
    if(hasDraw)
        type=1;
    dp[st][0]=0;
    findans(st);
    if(ans==-1)
    {
        if(type==1)
            cout<<"Draw"<<endl;
        else
            cout<<"Lose"<<endl;
    }
    else
    {
        int cnt=0;
        int state=0;
        for(int i=ans;i!=0;)
        {
            path[cnt]=i;
            cnt++;
            if(state==1)
            {
                i=dp[i][0];
                state=0;
            }
            else
            {
                i=dp[i][1];
                state=1;
            }
        }
        cout<<"Win"<<endl;
        for(int i=cnt-1;i>=0;i--)
            cout<<path[i]<<" ";
        cout<<endl;

}

}

Codeforces Round #467 (Div. 2) D. Sleepy Game相关推荐

  1. Codeforces Round #467 (Div. 1): B. Sleepy Game(BFS+有向图判环)

    题意(经过转换):给你一个n个点m条边的有向图,再给你一个起点x,问存不存在一条路径满足①路径中有奇数条边:②终点的出度为0,如果存在输出Win,并在第二行输出这个路径(可能不唯一输出任意一种),否则 ...

  2. Codeforces Round #467 (Div. 2)

    A Olympiad 输出除0以外的数字种数即可. B Vile Grasshoppers 猜想答案离y不会很远.暴力枚举答案, $O(\sqrt n)$验证,如果有因数落在区间$[2,p]$里就不合 ...

  3. Codeforces Round #467 (Div. 1): C. Lock Puzzle(构造)

    题目链接:http://codeforces.com/contest/936/problem/C 题意:给你一个起始字符串和一个目标字符串,你只有一种操作:选择一个数x,将后x个字母翻转,然后提取出来 ...

  4. Codeforces Round #467 (Div. 1): A. Save Energy!(公式)

    题意:Julia准备用她刚买的炉子煮鸡蛋,这个炉子开启之后会进入加热状态,但是k分钟之后就会自动停止并进入保温状态,在加热状态下鸡蛋会每秒获得2点热量,在保温状态下鸡蛋只会每秒获得1点热量,Julin ...

  5. Codeforces Round #748 (Div. 3) 题解 完整A~G

    Codeforces Round #748 (Div. 3) 题解 A. Elections 题意 已知竞选中三个候选人的当前得票数 a , b , c a,b,c a,b,c,现在可以增加任何一个人 ...

  6. Codeforces Round #506 (Div. 3)

    Codeforces Round #506 (Div. 3) 实习期间事不多,对div3 面向题解和数据编程了一波 A. Many Equal Substrings 题目链接 A题就是找后缀和前缀重合 ...

  7. Codeforces Round #563 (Div. 2)/CF1174

    Codeforces Round #563 (Div. 2)/CF1174 CF1174A Ehab Fails to Be Thanos 其实就是要\(\sum\limits_{i=1}^n a_i ...

  8. 构造 Codeforces Round #302 (Div. 2) B Sea and Islands

    题目传送门 1 /* 2 题意:在n^n的海洋里是否有k块陆地 3 构造算法:按奇偶性来判断,k小于等于所有点数的一半,交叉输出L/S 4 输出完k个L后,之后全部输出S:) 5 5 10 的例子可以 ...

  9. Codeforces Round #696 (Div. 2) (A ~ E)超高质量题解(每日训练 Day.16 )

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Codeforces Round #696 (Div. 2) (A ~ E)超高质量题解 比赛链接:h ...

  10. Codeforces Round #712 Div.2(A ~ F) 超高质量题解(每日训练 Day.15 )

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Codeforces Round #712 Div.2(A ~ F) 题解 比赛链接:https:// ...

最新文章

  1. 八 web爬虫讲解2—urllib库爬虫—ip代理—用户代理和ip代理结合应用
  2. html5中preclass,为什么HTML5建议把代码元素放在pre?
  3. 高特权级代码段转向低特权级代码段(利用 ret(retf) 指令实现 jmp from ring0 to ring3)
  4. mysql禁用历史命令_如何禁止mysql记录历史命令
  5. java 抛出异常效率_Java异常处理机制
  6. The Largest Clique UVA - 11324( 强连通分量 + dp最长路)
  7. 官网Tensorflow 移动开发流程
  8. WebLogic在Linux环境下安装
  9. nginx负载均衡 加权轮询和ip_hash
  10. mvc 根据模板导出excel,直接导出文件流
  11. 社区活动 | Apache RocketMQ × Apache Flink Meetup · 上海站
  12. 加速器instagram_“类似Instagram过滤器”标记肿瘤图像中的分子细节
  13. 微猫恋爱聊妹术V2小程序源码4.1.0多开版 附安装及前端调试教程
  14. 尝试导入导出Alembic动画模型(.abc)
  15. iZotope RX 7 Advanced混音插件使用教程
  16. 现代企业管理的12个指南针
  17. 运维工程师和网络工程师的差别在哪?到底哪个更有“钱”途?
  18. 显示购物车列表和修改商品数量
  19. 资本寒冬,毕业不满一年被裁,失业后我们如何自渡?
  20. 记2020年元宵节-我又回来了

热门文章

  1. blastn 输出结果每列啥意思_NCBI在线BLAST用法详解
  2. windows服务器如何搭建网站,Windows系列服务器网站搭建详细过程
  3. DOM事件总结(事件处理程序的类型及浏览器的兼容性)
  4. Python利用OpenGL实现控制三维对象运动-天体运动仿真
  5. php 微信 图片 文字 朋友圈,朋友圈实现图片+文字转发功能(必看篇)
  6. gromacs 安装_安装gromacs的一些心得
  7. php的chunk_split,php函数chunk_split详解
  8. 搭建IP代理池伪装IP地址
  9. 三星i919u android 6,SCH-I919U
  10. 拼多多“真香”补贴之变