题目链接

首先空格的移动等价于棋子在黑白格交替移动(设起点移向白格就是黑色),且不会走到到起点距离为奇数的黑格、到起点距离为偶数的白格(删掉就行了),且不会重复走一个格子。

(然后策略就同上题了,只不过第一步是走棋子)

还是考虑二分图最大匹配。如果起点不一定在最大匹配上,先手走到最大匹配点,后手沿最大匹配边走,先手要么无法走要么回到刚刚的情况,即先手必败(最大匹配是一条奇数长路径)。

反之,如果起点一定在最大匹配上,先手必胜。

判断一个点是否一定在最大匹配上可以先求一遍,再对非匹配点DFS。但是本题有多次移动,相当于删掉之前的点再求最大匹配。

如果删掉的点一定在最大匹配上,那么移动前该人必胜。

判断删的点是否一定在最大匹配中:首先当前在最大匹配中,其次删掉这个点x后,没有新的增广路(match[x]找不到新匹配)。

删点后记得清空连着的点的link啊。

//1212kb	36ms
#include <cstdio>
#include <cctype>
#include <algorithm>
//#define gc() getchar()
#define MAXIN 300000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
const int N=1605,M=N<<2; int n,m,mp[50][50],id[50][50],Enum,H[N],nxt[M],to[M],lk[N],Time,vis[N];
bool ban[N],ans[2005];
char IN[MAXIN],*SS=IN,*TT=IN; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
inline void AE(int u,int v)
{
to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum;
}
bool OK(int x)
{
vis[x]=Time;
for(int i=H[x],v; i; i=nxt[i])
if(vis[v=to[i]]!=Time && !ban[v])
{
vis[v]=Time;
if(!lk[v]||OK(lk[v])) return lk[v]=x,lk[x]=v,1;
}
return 0;
} int main()
{
n=read(),m=read(); int x=0,y=0;
for(int i=1; i<=n; ++i)
{
register char c=gc();
for(; c!='X'&&c!='O'&&c!='.'; c=gc());
for(int j=1; j<=m; ++j,c=gc())
if(c=='X') mp[i][j]=1;//black
else if(c=='O') mp[i][j]=0;//white
else x=i, y=j, mp[i][j]=1;
}
int f=(x+y)&1,tot=0;
for(int i=1; i<=n; ++i)
for(int j=1; j<=m; ++j)
if(mp[i][j]^f^((i+j)&1))//f^is_black^(i+j)&1
id[i][j]=++tot;
for(int i=1; i<=n; ++i)
for(int j=1; j<=m; ++j)
{
if(!id[i][j]) continue;//!
if(id[i+1][j]) AE(id[i][j],id[i+1][j]);
if(id[i][j+1]) AE(id[i][j],id[i][j+1]);
}
for(int i=1; i<=tot; ++i) if(!lk[i]/*!*/) ++Time, OK(i);
int K=read()<<1;
for(int i=1,p; i<=K; ++i)
{
ban[p=id[x][y]]=1;
if(lk[p]) ++Time, lk[lk[p]]=0/*清空!*/, ans[i]=!OK(lk[p]);//(x,y)是否是必胜态
x=read(), y=read();
}
int res=0;
for(int i=1; i<=K; i+=2) if(ans[i]&&ans[i+1]) ++res;
printf("%d\n",res);
for(int i=1; i<=K; i+=2) if(ans[i]&&ans[i+1]) printf("%d\n",i+1>>1); return 0;
}

BZOJ.2437.[NOI2011]兔兔与蛋蛋游戏(二分图博弈 匈牙利)的更多相关文章

  1. [NOI2011]兔兔与蛋蛋游戏 二分图博弈

    题面 题面 题解 通过观察,我们可以发现如下性质: 可以看做是2个人在不断移动空格,只是2个人能移动的边不同 一个位置不会被重复经过 : 根据题目要求,因为是按黑白轮流走,所以不可能重复经过一个点,不 ...

  2. [luogu1971 NOI2011] 兔兔与蛋蛋游戏 (二分图博弈)

    传送门 Solution 补一篇二分图博弈 这个博客写的很详细qwq: https://www.cnblogs.com/maijing/p/4703094.html Code //By Menteur ...

  3. bzoj 2437[Noi2011]兔兔与蛋蛋 黑白染色二分图+博弈+匈牙利新姿势

    noi2011 兔兔与蛋蛋 题目大意 直接看原题吧 就是\(n*m\)的格子上有一些白棋和一些黑棋和唯一一个空格 兔兔先手,蛋蛋后手 兔兔要把与空格相邻的其中一个白棋移到空格里 蛋蛋要把与空格相邻的其 ...

  4. bzoj 2437 [Noi2011]兔子和鸡蛋 [二分图匹配]

    叙述性说明 这些日子.兔子和蛋像一个新的棋盘游戏. 这场比赛是在 n 行 m 在船上进行列. 前,棋盘上有一 个格子是空的,其他的格子中都放置了一枚棋子,棋子或者是黑色,或者是白色. 每一局游戏总是兔 ...

  5. bzoj 2437: [Noi2011]兔兔与蛋蛋

    Description Solution 考虑犯错误的条件:之前是处于必胜状态,该操作之后就变成了必败状态. 我们可以把这个过程看成两人对网格图进行黑白染色,变成了一个二分图模型,即当前位置向相邻不同 ...

  6. BZOJ 1443 游戏(二分图博弈)

    新知识get. 一类博弈问题,基于以下条件: 1.博弈者人数为两人,双方轮流进行决策.2.博弈状态(对应点)可分为两类(状态空间可分为两个集合),对应二分图两边(X集和Y集).任意合法的决策(对应边) ...

  7. BZOJ.1443.[JSOI2009]游戏Game(二分图博弈 匈牙利)

    题目链接 \(Description\) 一个\(N*M\)的有障碍的棋盘,先手放置棋子后,从后手开始轮流移动棋子,不能走重复的位置,不能移动的输.求在哪些位置放棋子是先手必胜的. \(Solutio ...

  8. [bzoj]1059矩阵游戏<二分图匹配*匈牙利算法>

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1059 初见此题,我觉得这是水题,我认为只要每一行和每一列至少存在一个黑格就可以出现对角线, ...

  9. P1640 [SCOI2010]连续攻击游戏 二分图最大匹配 匈牙利算法

    题目描述 lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有2个属性,这些属性的值用[1,10000]之间的数表示.当他使用某种装备时,他只能使用该装备的某一个属性.并且每种装备 ...

随机推荐

  1. mysql安装与卸载(绿色版)

    1.下载压缩包,解压 2.配置环境变量 PATH:%MYSQL_HOME%\bin 3.在安装目录下新建my.ini配置文件: [mysql] default-character-set=utf8 [ ...

  2. C/C++杂记:虚函数的实现的基本原理

    1. 概述 简单地说,每一个含有虚函数(无论是其本身的,还是继承而来的)的类都至少有一个与之对应的虚函数表,其中存放着该类所有的虚函数对应的函数指针.例: 其中: B的虚函数表中存放着B::foo和B ...

  3. HTTP基础知识2

    引言 HTTP是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统.它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展.目前在WWW中使用的是HTTP/1. ...

  4. raindi python魔法函数(一)之__repr__与__str__

    __repr__和__str__都是python中的特殊方法,都是用来输出实例对象的,如果没有定义这两个方法在打印的时候只会输出实例所在的内存地址 这种方式的输出没有可读性,并不能直观的体现实例.py ...

  5. react之shouldComponentUpdate简单定制数据更新

    import React from 'react' class Demo extends React.Component{ constructor(props){ super(props) this. ...

  6. LeetCode(56):合并区间

    Medium! 题目描述: 给出一个区间的集合,请合并所有重叠的区间. 示例 1: 输入: [[1,3],[2,6],[8,10],[15,18]] 输出: [[1,6],[8,10],[15,18] ...

  7. Jquery----属性的利用

    属性操作: 1.属性 属性(如果你的选择器选出了多个对象,那么默认只会返回出第一个属性). attr(属性名|属性值) - 一个参数是获取属性的值,两个参数是设置属性值 - 点击加载图片示例 remo ...

  8. 格式化输出的方法:%、.format()、f

    a = '123'a1 = '456'a2 = '789' %占位符 text = "a=%s"%atext1 = "a=%s,a1=%s,a2=%s"%(a, ...

  9. Crack相关

    Microsoft Office 2007专业增强版密钥:KXFDR-7PTMK-YKYHD-C8FWV-BBPVWM7YXX-XJ8YH-WY349-4HPR9-4JBYJCTKXX-M97FT-8 ...

  10. centOS下单点部署k8s

    Kubernetes 是Google的一种基于容器的开源服务编排解决方案,在我们进行Kubernetes的学习前,为了对Kubernetes的工作有一个大概的认识, 我们需要先安装一个单节点的实例服务 ...