CodeForces 937D 936B Sleepy Game 有向图判环,拆点,DFS
题意:
一种游戏,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,就分开了,判环用原图,找答案用拆点的图

#include <bits/stdc++.h>
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define rep(ii,a,b) for(int ii=a;ii<=b;ii++)
using namespace std;
const int maxn=6e5+10;
const int maxm=1e6+10;
const int INF=0x3f3f3f3f;
int casn,n,m,k;
int head[maxn],nume;
struct node {int to,next;} e[maxm];
void add(int a,int b) {
e[++nume]=(node) {b,head[a]};
head[a]=nume;
}
int flag=0,draw=0;
int top,ans[maxn],s,vis[maxn];
void dfs(int now) {
int cnt=0;
vis[now]=1;
ans[++top]=now;
for(int i=head[now]; i; i=e[i].next) {
int to=e[i].to;
if(flag) return;
if(!vis[to])dfs(to);
cnt++;
}
if(now>n&&cnt==0)flag=1;
if(flag==0)top--;
}
int dfs2(int now){
if(vis[now]==2) return 1;
vis[now]=2;
for(int i=head[now];i;i=e[i].next){
int to=e[i].to;
if(!vis[to]){
if(dfs2(to))return 1;
}
else if(vis[to]==2) return 1;
}
vis[now]=1;
return 0;
}
int main() {
IO;
cin>>n>>m;
rep(i,1,n) {
int a,b;
cin>>a;
while(a--) {
cin>>b;
add(i+2*n,b+2*n);
add(i,b+n);
add(i+n,b);
}
}
cin>>s;
draw=dfs2(s+2*n);
top=0;
memset(vis,0,sizeof vis);
dfs(s);
if(flag) {
cout<<"Win\n";
for(int i=1; i<=top; i++) {
cout<<(ans[i]>n? ans[i]-n:ans[i])<<' ';
}
cout<<endl;
} else if(draw) cout<<"Draw\n";
else cout<<"Lose\n";
return 0;
}
CodeForces 937D 936B Sleepy Game 有向图判环,拆点,DFS的更多相关文章
- Dwarves (有向图判环)
Dwarves 时间限制: 1 Sec 内存限制: 64 MB提交: 14 解决: 4[提交][状态][讨论版] 题目描述 Once upon a time, there arose a huge ...
- COJ 3012 LZJ的问题 (有向图判环)
传送门:http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=1042 试题描述: LZJ有一个问题想问问大家.他在写函数时有时候很头疼,如 ...
- HDU 3342 Legal or Not(有向图判环 拓扑排序)
Legal or Not Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- HDU 5154 Harry and Magical Computer 有向图判环
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5154 题解: 有向图判环. 1.用dfs,正在访问的节点标记为-1,已经访问过的节点标记为1,没有访 ...
- Almost Acyclic Graph CodeForces - 915D (思维+拓扑排序判环)
Almost Acyclic Graph CodeForces - 915D time limit per test 1 second memory limit per test 256 megaby ...
- Codeforces 937 D. Sleepy Game(DFS 判断环)
题目链接: Sleepy Game 题意: Petya and Vasya 在玩移动旗子的游戏, 谁不能移动就输了. Vasya在订移动计划的时候睡着了, 然后Petya 就想趁着Vasya睡着的时候 ...
- POJ 1094 Sorting It All Out(拓扑排序+判环+拓扑路径唯一性确定)
Sorting It All Out Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 39602 Accepted: 13 ...
- Codeforces 937D - Sleepy Game
937D - Sleepy Game 思路: dfs. vis[u][0]==1表示u这个点能从s点偶数路径到达 vis[u][1]==1表示u这个点能从s点奇数路径到达 这个样就能保证dfs时每个点 ...
- 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 ...
随机推荐
- Kafka技术内幕 读书笔记之(五) 协调者——延迟的加入组操作
协调者处理不同消费者的“加入组请求”,由于不能立即返回“加入组响应”给每个消费者,它会创建一个“延迟操作”,表示协调者会延迟发送“加入组响应”给消费者 . 但协调者不会为每个消费者的 “加入组请求 ...
- spring MVC页面的重定向
如图,一个jsp页面跳转到下一个jsp页面通常需要上一个页面发出带有参数得请求,我们都知道spring MVC是不能直接跳页面的. 需要配置视图解析器,通过返回视图名再跳转到相应得JSP页面. 即使这 ...
- HDU 1021(斐波那契数与因子3 **)
题意是说在给定的一种满足每一项等于前两项之和的数列中,判断第 n 项的数字是否为 3 的倍数. 斐波那契数在到第四十多位的时候就会超出 int 存储范围,但是题目问的是是否为 3 的倍数,也就是模 3 ...
- threading.local学习
多线程抢占问题 import time import threading obj = 5 def task(arg): global obj obj = arg time.sleep(1) print ...
- [Windows] [VS] [C] [取得指针所指内存的二进制形式字符]
// 取得指针所指内存的十六进制形式字符串,size指定字节长度#define Mem_toString(address, size) _Mem_toString((PBYTE)address, si ...
- HTML 5 Web 本地存储
1.使用localStorage 2.使用sessionStorage 两者区别1关闭网页不失效,2失效.用法示例 localStorage.setItem(“key”,“value”)//存储 lo ...
- SSH中使用延迟加载报错Exception occurred during processing request: could not initialize proxy - no Session
17:40:17,249 ERROR DefaultDispatcherErrorHandler:42 - Exception occurred during processing request: ...
- 三十七、Linux 线程——线程清理和控制函数、进程和线程启动方式比较、线程的状态转换
37.1 线程清理和控制函数 #include <pthread.h> void pthread_cleanup_push(void (* rtn)(void *), void *arg) ...
- 字符设备驱动(一)---led
一.总体架构 二.硬件电路 1.硬件原理图 2.寄存器配置 三.代码编写 写linux的设备驱动操作的是系统的虚拟地址,并不是像裸机程序一样操作的是物理地址. 物理地址要映射成虚拟地址,就要用到ior ...
- Gossip
http://www.cnblogs.com/xingzc/p/6165084.html 敬请期待...