题目链接

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

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

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

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

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

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

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

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

  1. //1212kb 36ms
  2. #include <cstdio>
  3. #include <cctype>
  4. #include <algorithm>
  5. //#define gc() getchar()
  6. #define MAXIN 300000
  7. #define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
  8. const int N=1605,M=N<<2;
  9. int n,m,mp[50][50],id[50][50],Enum,H[N],nxt[M],to[M],lk[N],Time,vis[N];
  10. bool ban[N],ans[2005];
  11. char IN[MAXIN],*SS=IN,*TT=IN;
  12. inline int read()
  13. {
  14. int now=0;register char c=gc();
  15. for(;!isdigit(c);c=gc());
  16. for(;isdigit(c);now=now*10+c-'0',c=gc());
  17. return now;
  18. }
  19. inline void AE(int u,int v)
  20. {
  21. to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
  22. to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum;
  23. }
  24. bool OK(int x)
  25. {
  26. vis[x]=Time;
  27. for(int i=H[x],v; i; i=nxt[i])
  28. if(vis[v=to[i]]!=Time && !ban[v])
  29. {
  30. vis[v]=Time;
  31. if(!lk[v]||OK(lk[v])) return lk[v]=x,lk[x]=v,1;
  32. }
  33. return 0;
  34. }
  35. int main()
  36. {
  37. n=read(),m=read(); int x=0,y=0;
  38. for(int i=1; i<=n; ++i)
  39. {
  40. register char c=gc();
  41. for(; c!='X'&&c!='O'&&c!='.'; c=gc());
  42. for(int j=1; j<=m; ++j,c=gc())
  43. if(c=='X') mp[i][j]=1;//black
  44. else if(c=='O') mp[i][j]=0;//white
  45. else x=i, y=j, mp[i][j]=1;
  46. }
  47. int f=(x+y)&1,tot=0;
  48. for(int i=1; i<=n; ++i)
  49. for(int j=1; j<=m; ++j)
  50. if(mp[i][j]^f^((i+j)&1))//f^is_black^(i+j)&1
  51. id[i][j]=++tot;
  52. for(int i=1; i<=n; ++i)
  53. for(int j=1; j<=m; ++j)
  54. {
  55. if(!id[i][j]) continue;//!
  56. if(id[i+1][j]) AE(id[i][j],id[i+1][j]);
  57. if(id[i][j+1]) AE(id[i][j],id[i][j+1]);
  58. }
  59. for(int i=1; i<=tot; ++i) if(!lk[i]/*!*/) ++Time, OK(i);
  60. int K=read()<<1;
  61. for(int i=1,p; i<=K; ++i)
  62. {
  63. ban[p=id[x][y]]=1;
  64. if(lk[p]) ++Time, lk[lk[p]]=0/*清空!*/, ans[i]=!OK(lk[p]);//(x,y)是否是必胜态
  65. x=read(), y=read();
  66. }
  67. int res=0;
  68. for(int i=1; i<=K; i+=2) if(ans[i]&&ans[i+1]) ++res;
  69. printf("%d\n",res);
  70. for(int i=1; i<=K; i+=2) if(ans[i]&&ans[i+1]) printf("%d\n",i+1>>1);
  71. return 0;
  72. }

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. ubuntu 14.04 软件中心闪退解决方案

    法一: gksudo gedit /usr/share/software-center/softwarecenter/ui/gtk3/views/lobbyview.py 注释下面这句话(注释使用#号 ...

  2. Jetson tk1 hash sum mismatch

    sudo apt-get update遭遇Hash Sum Mismatch 修改DNS服务器地址: sudo gedit /etc/resolv.conf 解决办法: 在装有goagent的情况下: ...

  3. 【转】Shell编程基础篇-下

    [转]Shell编程基础篇-下 1.1 条件表达式 1.1.1 文件判断 常用文件测试操作符 常用文件测试操作符 说明 -d文件,d的全拼为directory 文件存在且为目录则为真,即测试表达式成立 ...

  4. 经典]Linux内核中ioremap映射的透彻理解【转】

    转自:http://blog.csdn.net/lanyang123456/article/details/7403514 几乎每一种外设都是通过读写设备上的寄存器来进行的,通常包括控制寄存器.状态寄 ...

  5. mysql安装与卸载(阿里云)

    1.安装rpm包rpm -Uvh http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm 2.安装mysqlyum -y i ...

  6. odoo之model参数属性1

    1.基础文件及目录结构 在认识odoo ORM框架前,先介绍一下odoo中模块目录结构.   data:存放模块预制数据 i18n:存放国际化文件 models:存放模型等py代码 security: ...

  7. Qt Ubuntu 编译出错-1: error: 找不到 -lGL

    安装好,编译界面程序出错“-1: error: 找不到 -lGL” 在终端运行如下命令(安装Qt5.8.0) sudo apt-get install libqt5-dev sudo apt-get ...

  8. TCP端口转发(centos7)

    =============================================== 2019/2/14_第1次修改                       ccb_warlock == ...

  9. [java]用md5来判断两个文件是否完全相同

    1. 前言 由于相比较两张图片是否是相同,如果通过像素点比较感觉速度比较慢,当很多图片进行比较时,效率就低很多了.由于每个文件md5基本上是唯一的,所以用获取文件的md5来判断是否相同文件. 2. 代 ...

  10. javascript 判断属性是否存在

    判断一个实例是否存在某个属性的方法使用 "in" var Student = { name: "Robot", height: 1.2, sex: " ...