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 ...
随机推荐
- @GetMapping(value="/") , "/" 可加可不加 ,是不是一样的
@GetMapping(value = "/user") 和 @GetMapping(value = "user") 的区别 1.带上 "/&quo ...
- [leetcode-108,109] 将有序数组转换为二叉搜索树
109. 有序链表转换二叉搜索树 Given a singly linked list where elements are sorted in ascending order, convert it ...
- JQ和Js获取span标签的内容
JQ和Js获取span标签的内容 html: 1 <span id="content">‘我是span标签的内容’</span> javascript获取: ...
- vuex中strict严格模式
开启严格模式,仅需在创建 store 的时候传入strict: true const store = new Vuex.Store({ state, strict:true//开启严格模式后,只能通过 ...
- 015、调试Dockerfile(2019-01-04 周五)
参考https://www.cnblogs.com/CloudMan6/p/6853329.html Dockerfile构建镜像的过程 1.从base镜像运行一个容器 2.执行一条指令,对容 ...
- Android圆角矩形
1.在drawable中创建shape_round文件 <?xml version="1.0" encoding="utf-8"?> <sha ...
- Ubuntu中在服务器和本机之间传递文件
首先可以通过root进入到服务器中,(登录方法在下面讲解)为自己创建一个用户. useradd的选项: 选项: -b, --base-dir BASE_DIR 新账户的主目录的基目录 -c, --co ...
- html页面高度问题
首先,上图 说明 1. clientHeight大部分浏览器对 clientHeight 都没有什么异议,都认为是内容可视区域的高度,也就是说页面浏览器中可以看到内容的这个区域的高度,即然是指可看到内 ...
- ES6走一波 字符串的扩展
ES6字符串扩展: 处理大码点字符 字符的Unicode表示法 \uxxxx表示一个字符串,超出 \u0000 ~ \uffff范围,必须用两个双字节形式表示. ES6改进为 将码点放到大括号 可正确 ...
- yum2
首先yum源的主配置文件为/etc/yum.conf文件.这个文件一般不用动,而我们配置具体的各个yum源的配置文件在/etc/yum.repo.d目录下,所有以repo结尾的文件都是yum源配置文件 ...