题意:

  一种游戏,2个人轮流控制棋子在一块有向图上移动,每次移动一条边,不能移动的人为输,无限循环则为平局,棋子初始位置为$S$

  现在有一个人可以同时控制两个玩家,问是否能使得第一个人必胜,并输出一个解,否则判断是否能平局

题解:

  看到这个题首先我想到了强连通分量,但是事实证明求出强连通分量,缩点对解决问题没有什么帮助....

  能写一些看似正确的算法,但其实是假算法来的..

  

  ...........

  所以应该先分析策略,肯定是能赢就赢,不能赢就求平局,最后才算输

  平局很好判断,有向图上,从$S$点跑一边DFS,如果起点的可达子图包含环,就能平局了,具体方法类似tarjan

  其次是判断赢,简单来说就是棋子到达了一个点,路径长度为奇数(可以经过环),且这个点没有出边了

  换句话说,对于每一个点,其实有2种情况,第一个情况是你到达了这个点,到起点的距离是偶数,那肯定不会是终点了

                   第二个情况是你到达了这个点,到起点的距离是奇数,这时候如果还没有出边,那就是答案了,保存当前这个函数堆栈里的点即可

  可是,问题在于,你可以经过一个环,来使得距离变为奇数,没法简单的DFS

  我们考虑,到达每个点时有两种情况,那就是距离起点的距离奇/偶,因此考虑拆点

  把每个点拆开,分别代表奇点和偶点,每次加边的时候,把点一分为三

  $[1,n]$偶数点,$[n+1,2*n]$ 奇数点 $[2n+1,3n]$ 原图

  对于输入的边$(a,b)$,先保存原图,再连2条边,$(a,b+n),(a+n,b)$ 表示如果当前点是偶数距离,距离加一就会变成奇数,反之亦然

  意义在于,这个新的图包含了将"绕一个奇数长度的环,将偶数距离变成奇数距离"这种操作

  如果是奇数长度的环,在环路的尽头会连接到另外一个偶数距离,而偶数长度的环,则不连通

  然后就$O(2(m+n))$的DFS即可

  我试着把判环和找答案放在一个DFS里,但是不太好写,容易TLE,就分开了,判环用原图,找答案用拆点的图

  

  1. #include <bits/stdc++.h>
  2. #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
  3. #define rep(ii,a,b) for(int ii=a;ii<=b;ii++)
  4. using namespace std;
  5. const int maxn=6e5+10;
  6. const int maxm=1e6+10;
  7. const int INF=0x3f3f3f3f;
  8. int casn,n,m,k;
  9. int head[maxn],nume;
  10. struct node {int to,next;} e[maxm];
  11. void add(int a,int b) {
  12. e[++nume]=(node) {b,head[a]};
  13. head[a]=nume;
  14. }
  15. int flag=0,draw=0;
  16. int top,ans[maxn],s,vis[maxn];
  17. void dfs(int now) {
  18. int cnt=0;
  19. vis[now]=1;
  20. ans[++top]=now;
  21. for(int i=head[now]; i; i=e[i].next) {
  22. int to=e[i].to;
  23. if(flag) return;
  24. if(!vis[to])dfs(to);
  25. cnt++;
  26. }
  27. if(now>n&&cnt==0)flag=1;
  28. if(flag==0)top--;
  29. }
  30. int dfs2(int now){
  31. if(vis[now]==2) return 1;
  32. vis[now]=2;
  33. for(int i=head[now];i;i=e[i].next){
  34. int to=e[i].to;
  35. if(!vis[to]){
  36. if(dfs2(to))return 1;
  37. }
  38. else if(vis[to]==2) return 1;
  39. }
  40. vis[now]=1;
  41. return 0;
  42. }
  43. int main() {
  44. IO;
  45. cin>>n>>m;
  46. rep(i,1,n) {
  47. int a,b;
  48. cin>>a;
  49. while(a--) {
  50. cin>>b;
  51. add(i+2*n,b+2*n);
  52. add(i,b+n);
  53. add(i+n,b);
  54. }
  55. }
  56. cin>>s;
  57. draw=dfs2(s+2*n);
  58. top=0;
  59. memset(vis,0,sizeof vis);
  60. dfs(s);
  61. if(flag) {
  62. cout<<"Win\n";
  63. for(int i=1; i<=top; i++) {
  64. cout<<(ans[i]>n? ans[i]-n:ans[i])<<' ';
  65. }
  66. cout<<endl;
  67. } else if(draw) cout<<"Draw\n";
  68. else cout<<"Lose\n";
  69. return 0;
  70. }

  

CodeForces 937D 936B Sleepy Game 有向图判环,拆点,DFS的更多相关文章

  1. Dwarves (有向图判环)

    Dwarves 时间限制: 1 Sec  内存限制: 64 MB提交: 14  解决: 4[提交][状态][讨论版] 题目描述 Once upon a time, there arose a huge ...

  2. COJ 3012 LZJ的问题 (有向图判环)

    传送门:http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=1042 试题描述: LZJ有一个问题想问问大家.他在写函数时有时候很头疼,如 ...

  3. HDU 3342 Legal or Not(有向图判环 拓扑排序)

    Legal or Not Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  4. HDU 5154 Harry and Magical Computer 有向图判环

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5154 题解: 有向图判环. 1.用dfs,正在访问的节点标记为-1,已经访问过的节点标记为1,没有访 ...

  5. Almost Acyclic Graph CodeForces - 915D (思维+拓扑排序判环)

    Almost Acyclic Graph CodeForces - 915D time limit per test 1 second memory limit per test 256 megaby ...

  6. Codeforces 937 D. Sleepy Game(DFS 判断环)

    题目链接: Sleepy Game 题意: Petya and Vasya 在玩移动旗子的游戏, 谁不能移动就输了. Vasya在订移动计划的时候睡着了, 然后Petya 就想趁着Vasya睡着的时候 ...

  7. POJ 1094 Sorting It All Out(拓扑排序+判环+拓扑路径唯一性确定)

    Sorting It All Out Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 39602   Accepted: 13 ...

  8. Codeforces 937D - Sleepy Game

    937D - Sleepy Game 思路: dfs. vis[u][0]==1表示u这个点能从s点偶数路径到达 vis[u][1]==1表示u这个点能从s点奇数路径到达 这个样就能保证dfs时每个点 ...

  9. Codeforces Round #460 (Div. 2): D. Substring(DAG+DP+判环)

    D. Substring time limit per test 3 seconds memory limit per test 256 megabytes input standard input ...

随机推荐

  1. 7.Hystrix-服务熔断

    服务熔断 类似现实生活中的“保险丝“,当某个异常条件被触发,直接熔断保险丝来起到保护电路的作用, 熔断的触发条件可以依据不同的场景有所不同,比如统计一个时间窗口内失败的调用次数. 1.断路器状态机: ...

  2. JAVA-8大基本类型与包装类的例子(基础必备)

    package com.net.xinfang.reflect; /*** * 8种基本类型(byte,int,short,long,float,double,char,boolean) * 布尔型只 ...

  3. golang interface

    接口定义 Interface类型可以定义一组方法,但是这些不需要实现.并且interface不能 包含任何变量. type Interface interface { test1(a, b int) ...

  4. Python复习笔记(六)网络编程(udp/tcp)

    一.网络-udp(用户数据报协议) 用户数据报协议 类似写信,不安全,数据有可能丢 1.1 ip地址 注意: IP地址127.0.0.1 ~ 127.255.255.255 用于回路测试 私有ip地址 ...

  5. windows server 2008 r2 负载平衡 找不到主机 解决方案

    在C:\Windows\System32\drivers\etc文件夹中的host文件里手工将主机名WIN-********解析至IP 即可.

  6. WEBGIS网页崩溃问题分析

    加载某一地区的系统页面时,过了几十秒,页面空白.曾经捕获到是WMTS服务异常的问题.本人推测可能是底图服务停止,使得WMTS服务无法进行而抛出的异常. 为了证实自己的猜想,鄙人对一个正常的系统,修改为 ...

  7. SpringBoot系列: 极简Demo程序和Tomcat war包部署

    =================================SpringBoot 标准项目创建步骤================================= 使用 Spring IDE( ...

  8. Slash and BackSlash 记忆法

    容易混淆的两兄弟 Slash https://en.wikipedia.org/wiki/Slash Slash (punctuation), the "/" punctuatio ...

  9. 破解修改 Electron 软件 | 游戏

    Electron 是 Github 发布跨平台桌面应用开发工具,支持 Web 技术开发桌面应用开发,其本身是基于 C++ 开发的,GUI 核心来自于 Chrome,而 JavaScript 引擎使用 ...

  10. Bootstrap响应式导航

    <nav class="navbar navbar-default" role="navigation"> <div class=" ...