P6970 [NEERC2016] Game on Graph

P6970 [NEERC2016] Game on Graph

[NEERC2016] Game on Graph

题面翻译

Gennady 和 Georgiy 在玩一个有向图上的游戏。这个图有 n 个点 m 条边,两人轮流操作,每次可以将棋子沿着其中一条边移动,不能移动者输。

你要对于每个点,分别求出以这个店为起点开始游戏,两人分别作为先手,最终会输,赢,还是平局(游戏无限循环)。

其中,Gennady 因为玩得很开心,所以他更期望将游戏变为平局;Georgiy 还有很多其他事,所以他更期望游戏不要平局。当然,在不平局的基础上,两人都更希望赢。

输入格式

第一行两个数 nm 表示有 n 个点 m 条边。
接下来 m 行每行两个数 a,b 表示一条由 ab 的边。

输出格式

两行,第一行表示分别以每一个点为起点 Gennady 先手的胜负情况;第二行表示分别以每一个点为起点 Georgiy 先手的胜负情况。W 表示赢,L 表示输,D 表示平局。

by a___

(1≤n≤100000)
(1≤m≤200000)
Time limit: 2 s, Memory limit: 512 MB.
---------------------------------------------------------------------------------------

将每个点拆成A,B两类;
对于一个点u及其邻居v:

用opt=0代表A类节点,opt=1代表B类节点

对于A类点v.A:
如果它的所有u.A已经被遍历过了,那就搜索v.a这个节点。
(因为A希望平局,所以要先确定他邻居点的状态再确定他)

对于B类点v.B:
如果它没有被访问过,那就访问v.B这个节点
(因为B不希望平局,所以只要能访问就访问)

注意:在主程序中用for遍历启动搜索时,只有那些d==0的节点才能被搜
(即状态已经确定的节点)

然后,我们在第一次搜索完之后统计所有节点的胜负
而对于胜负的判定:(对于第一次搜素)

若对于 vis[0][opt]=1:
说明其被访问过即度数已经为0则A输了,反之,暂定A赢了

若对于 vis[1][opt]=1:
说明其被访问过即度数已经为0则B赢了,反之,暂定B输了

(因为B在第一次dfs中为后手,所以要反过来)

再进行第二次搜索,而在两次搜索中都未被确定的节点就是平局了

然后这题就做完了

Code:

#include<bits/stdc++.h>
const int N=1e5+5;
using namespace std;
vector<int> E[N];
int d[N][2],vis[N][2];
char ans[2][N];
int n,m;
void dfs(int u,int opt)
{
vis[u][opt]=1;
for(int v : E[u])
{
d[v][opt^1]--;
if(opt==0&&vis[v][1]==0)dfs(v,1);//对于B类点,只要先前没遍历过,就搜一下
if(opt==1&&d[v][0]==0)dfs(v,0);//对于A类点,要等到所有邻居被访问过之后才能搜
}
}
void work()
{
cin>>n>>m;
for(int i=1,x,y;i<=m;i++)
{
scanf("%d%d",&x,&y);
E[y].push_back(x);//建反图,由已知确定未知
d[x][1]++,d[x][0]++;//两类点的度数
}
for(int i=1;i<=n;i++)
{
if(d[i][0]==0&&vis[i][0]==0)
{
dfs(i,0);
}
}
for(int i=1;i<=n;i++)
{
if(vis[i][0])
{
ans[0][i]='L';
}
else
{
ans[0][i]='W';
}
if(vis[i][1])
{
ans[1][i]='W';
}
else
{
ans[1][i]='L';
}
}
for(int i=1;i<=n;i++)
{
if(!d[i][1]&&!vis[i][1])dfs(i,1);
}
for(int i=1;i<=n;i++)
{
if(!vis[i][1])ans[1][i]='D';
if(!vis[i][0])ans[0][i]='D';
}
for(int opt=0;opt<2;opt++)
{
for(int i=1;i<=n;i++)
{
putchar(ans[opt][i]);
}
cout<<"\n";
}
}
int main()
{
//freopen("P6970.in","r",stdin);//freopen("P6970.out","w",stdout);
work();
}
posted @   liuboom  阅读(12)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示