Description

绿色游戏是一种两人游戏,双方分别称Ann和Billy。游戏的内容主要是轮流在棋盘上移动一颗棋子。棋盘上的点一部分是绿色的,其余是白色的;全部从1至a+b编号。编号1至a的点属于Ann,编号(a+1)至(a+b)的点属于Billy。每个点都有一些后继点,均可一步到达。属于Ann的点的后继点一定属于Billy,反之亦然。所有的点都至少有一个后继点,这样总可以往下走一步。游戏开始时把棋子放在任意的一点P上,然后双方轮流移动棋子至当前所在点(属于移动方)的一个后继点上(属于对手)。游戏由点P的拥有者开始,结束时棋子第二次到达了某一点,称点Q。如果在从点Q至点Q的一连串移动中,棋子至少一次被放到绿色点上,则Ann赢。若从点P开始,不管Billy如何移动,Ann总能保证赢得这次游戏,则称Ann对起始点P有必胜的策略。

任务: 算出Ann有必胜策略的起始点;

Input

首行有两个整数a和b,两个整数之间用一个空格分开,分别表示属于Ann和Billy的点数(1小于等于a,b小于等于3000)。

以下a+b行是对各点的描述,先描述Ann的点,再描述Billy的点。

第i+1行(1小于等于i小于等于a+b)以整数z,k开始:z表示点i的颜色(O-白色,I-绿色),k表示后继点的数目。

然后是K个整数(1小于等于k<a+b),写在同一行,代表点i后继点的编号,这些整数均用一个空格分开。

绿点的个数不超过100,所有点的后继点的个数之和不超过30000。

Output

首行仅一个整数L,代表Ann有L个有必胜策略的起始点。以下L行按升序顺序依次给出这些点的编号。

Sample Input

5 3

0 2 6 7

0 3 6 7 8

0 1 8

1 1 7

1 1 8

1 2 1 2

0 2 1 2

0 2 3 4

Sample Output

5

1

2

4

6

7


维护一个保护集合\(S\),表示哪些点\(A\)可能胜利。

首先将所有绿点加入\(S\)。

\(1.\)对于一个不在\(S\)的\(A\)点,若它存在某个后继在\(S\)中,则将其加入\(S\)。

\(2.\)对于一个不在\(S\)的\(B\)点,若它所有后继都在\(S\)中,则将其加入\(S\)。

通过拓扑可以\(O(n+m)\)求出\(S\)集合,那么剩下的点\(A\)必败。

\(1.\)对于一个在\(S\)的\(A\)点,若它所有后继都不在\(S\)中,则将其从\(S\)中移除。

\(2.\)对于一个在\(S\)的\(B\)点,若它存在某个后继不在\(S\)中,则将其从\(S\)中移除。

同样可以通过拓扑\(O(n+m)\)求出最终的\(S\)集合。

这样会导致某些绿点不在\(S\)中,那么它们就失去了作为绿点的价值,将其标记为白点。

重复运行这个算法\(O(n)\)轮直到所有绿点都发挥了价值,此时\(S\)中的点\(A\)必胜。

时间复杂度\(O(n(n+m))\)。

/*program from Wolfycz*/
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define inf 0x7f7f7f7f
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef unsigned long long ull;
inline int read(){
int x=0,f=1;char ch=getchar();
for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
return x*f;
}
inline void print(int x){
if (x>=10) print(x/10);
putchar(x%10+'0');
}
const int N=3e3,M=3e4;
int pre[M+10],now[N+10],child[M+10],d[N+10],deg[N+10],h[N+10],Ans[N+10];
bool vis[N+10],c[N+10];
int n,m,tot;
void join(int x,int y){pre[++tot]=now[x],now[x]=tot,d[child[tot]=y]++;}
bool solve(){
int head=1,tail=0;
for (int i=1;i<=n;i++){
vis[i]=c[i],deg[i]=d[i];
vis[i]?h[++tail]=i:0;
}
for (;head<=tail;head++){
int Now=h[head];
for (int p=now[Now],son=child[p];p;p=pre[p],son=child[p]){
if (vis[son]) continue;
son<=m?vis[h[++tail]=son]=1:!--deg[son]?vis[h[++tail]=son]=1:0;
}
}
head=1,tail=0;
for (int i=1;i<=n;i++){
deg[i]=d[i];
!vis[i]?h[++tail]=i:0;
}
for (;head<=tail;head++){
int Now=h[head];
for (int p=now[Now],son=child[p];p;p=pre[p],son=child[p]){
if (!vis[son]) continue;
son>m?vis[h[++tail]=son]=0:!--deg[son]?vis[h[++tail]=son]=0:0;
}
}
bool flag=0;
for (int i=1;i<=n;i++) if (c[i]&&!vis[i]) c[i]=0,flag=1;
return flag;
}
int main(){
m=read(),n=read()+m;
for (int i=1,k;i<=n;i++){
c[i]=read(),k=read();
for (int j=1;j<=k;j++) join(read(),i);
}
while (solve());
int cnt=0;
for (int i=1;i<=n;i++) if (vis[i]) Ans[++cnt]=i;
printf("%d\n",cnt);
for (int i=1;i<=cnt;i++) printf("%d\n",Ans[i]);
return 0;
}

[POI2001]Gra绿色游戏的更多相关文章

  1. BZOJ2948 : [Poi2001]绿色游戏

    维护一个保护集合$S$,表示哪些点$A$可能胜利. 首先将所有绿点加入$S$. $1.$对于一个不在$S$的$A$点,若它存在某个后继在$S$中,则将其加入$S$. $2.$对于一个不在$S$的$B$ ...

  2. 游戏行业DDoS攻击解决方案

    行业综述 根据全球游戏和全球移动互联网行业第三方分析机构Newzoo的数据显示:2017年上半年,中国以275亿美元的游戏市场收入超过美国和日本,成为全球榜首. 游戏行业的快速发展.高额的攻击利润.日 ...

  3. 阿里云:游戏行业DDoS攻击解决方案

    转自:http://www.gamelook.com.cn/2018/01/319420 根据全球游戏和全球移动互联网行业第三方分析机构Newzoo的数据显示:2017年上半年,中国以275亿美元的游 ...

  4. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  5. 病毒木马查杀实战第013篇:一个基于.NET的“敲竹杠”病毒研究

    前言 恶意程序发展至今,其功能已经从最初的单纯破坏,不断发展为隐私的窥探,信息的盗取,乃至如今非常流行的"敲竹杠"病毒,用于勒索.可见随着时代的发展,病毒的作者们往往也是想利用自己 ...

  6. MMORPG大型游戏设计与开发(攻击区域 扇形)

    距离上次发布已经有了很长一段时间,期间由于各种原因没有更新这方面的技术分享,在这里深表遗憾.在MMO或其他的游戏中,会有针对各种形状的计算,通常在攻击区域里不会很复杂,常见的为矩形.圆形.扇形.今天分 ...

  7. 网页闯关游戏(riddle webgame)--H5刮刮卡的原理和实践

    前言: 之前编写了一个网页闯关游戏(类似Riddle Game), 除了希望大家能够体验一下我的游戏外. 也愿意分享编写这个网页游戏过程中, 学到的一些知识. 对于刮刮卡, 想必大家都很熟悉, 也很喜 ...

  8. Unity关于获取游戏对象

    我觉得Unity里面的Transform 和 GameObject就像两个双胞胎兄弟一样,这俩哥们很要好,我能直接找到你,你也能直接找到我.我看很多人喜欢在类里面去保存GameObject对象.解决G ...

  9. 转载:[转]如何学好3D游戏引擎编程

      [转]如何学好3D游戏引擎编程 Albert 本帖被 gamengines 从 游戏引擎(Game Engine) 此文为转载,但是值得一看. 此篇文章献给那些为了游戏编程不怕困难的热血青年,它的 ...

随机推荐

  1. ArcEngine读取ShapeFile时,出现乱码的解决方案

    ArcEngine读取ShapeFile时,如果用LicenseControl的话,字段中含有汉字时可以正常使用,当使用LicenseInitializer进行初始化时,读取含有汉字的字段时,就会出现 ...

  2. 关于maven的规则插件:Maven Enforcer plugin

    Maven提供了Maven-Enforcer-Plugin插件,用来校验约定遵守情况(或者说校验开发环境).比如JDK的版本,Maven的版本,开发环境(Linux,Windows等),依赖jar包的 ...

  3. python执行

    转载:https://www.cnblogs.com/zflibra/p/4180796.html

  4. 如何利用Fluxion诱惑目标用户获取WPA密码

      前言 由于ISP替代了易受攻击的路由器,供渗透测试人员选择的诸如Reaver这样的工具越来越少,对于特定的目标,哪些工具有用与否能够确定的也很少.而如果采用暴力破解WPA密码,可能会需要大量的时间 ...

  5. 条款一:尽量使用const、inline而不是#define

    #define ASPECT_RATIO 1.653 编译器会永远也看不到ASPECT_RATIO这个符号名,因为在源码进入编译器之前,它会被预处理程序去掉,于是ASPECT_RATIO不会加入到符号 ...

  6. NoSQL之Memcached

    一.Memcached概念 Memcached是NoSQL产品之中的一个,是一个暂时性键值存储NoSQL数据库,过去被大量使用在互联网站点中,作为应用和数据库之间的缓存层,大大提高查询和訪问速度. M ...

  7. [Bash] Move and Copy Files and Folders with Bash

    In this lesson we’ll learn how to move and rename files (mv) and copy (cp) them. Move index.html to ...

  8. 什么是WPF? 秒懂 !

    一開始听到WPF.认为非常陌生.在百度百科等地方看完简单介绍之后.感觉更深奥.各种不懂啊! 在简单做了几个页面之后,发现.原来如此! So Easy 但又So Magic. 为什么说它简单?由于它简直 ...

  9. 浅谈 ZipArchive 类

    Microsoft .NET Framework 4.5 新增了 ZipArchive 类 Microsoft Windows 8 Consumer Preview 操作系统已经内置了 Microso ...

  10. create-react-app 使用 webpack 打包压缩失败

    问题,正常 npm run build 打包后,发现打包后的文件异常大,有 > 20M 的大小 分析, 1.起初以为是代码本身过大的原因导致的,所以一直在想如何进行代码拆分使得文件能尽可能的小, ...