传送门

显然是个二分图,设开始位置是左边,另一边是右边

那么先手是把左边挪到右边,后手是把右边挪到左边,不能挪的那方失败

结论:Alice必胜当且仅当开始位置不一定在最大匹配上

必要性:

如果开始位置不在最大匹配上,那一定有种匹配方案不包含开始位置(废话)

考虑这种方案,由于左边已经空出来了,所以右边和它连通的点都已经有匹配。

这样Bob移动到哪里,Alice就移到它的匹配点,这样Alice必胜。

充分性:

考虑逆否命题,如果开始位置一定在最大匹配上,那么Bob必胜。

①如果右边有和开始位置相邻的未匹配点

Bob移到这个位置,然后转换为了上面的情况

②如果没有

那就移到匹配点

因为开始点一定在最大匹配上,所以移了之后找不到未匹配点

同理后面如果左边有未匹配点就找到了一条增广路,矛盾

这样可以一直走匹配点直到胜利

所以先跑个最大匹配,从未匹配点开始dfs,对所有与之相邻点给匹配点打上标记

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cctype>
#define MAXN 10005
#define MAXM 50005
using namespace std;
struct edge{int u,v;}e[MAXM];
int head[MAXN],nxt[MAXM],cnt;
void addnode(int u,int v)
{e[++cnt]=(edge){u,v};nxt[cnt]=head[u];head[u]=cnt;
}
int n,m;
char s[105][105];
#define id(x,y) (((x)-1)*m+(y))
const int dx[]={-1,1,0,0},dy[]={0,0,-1,1};
int link[MAXN],used[MAXN];
bool find(int u,int mark)
{for (int i=head[u];i;i=nxt[i])if (used[e[i].v]!=mark){used[e[i].v]=mark;if (!link[e[i].v]||find(link[e[i].v],mark)) return link[e[i].v]=u,true;}return false;
}
bool ans[MAXN];
void dfs(int u)
{for (int i=head[u];i;i=nxt[i])if (!ans[link[e[i].v]]){ans[link[e[i].v]]=true;dfs(link[e[i].v]);}
}
int main()
{scanf("%d%d",&n,&m);for (int i=1;i<=n;i++) scanf("%s",s[i]+1);for (int x=1;x<=n;x++)for (int y=1;y<=m;y++)if (s[x][y]=='.'&&(x+y)&1)for (int i=0;i<4;i++)if (s[x+dx[i]][y+dy[i]]=='.')addnode(id(x,y),id(x+dx[i],y+dy[i]));int d=0;for (int x=1;x<=n;x++)for (int y=1;y<=m;y++)if (s[x][y]=='.'&&(x+y)&1)d+=find(id(x,y),id(x,y)),ans[id(x,y)]=1;cerr<<d<<endl;for (int x=1;x<=n;x++)for (int y=1;y<=m;y++)if (s[x][y]=='.'&&!((x+y)&1))link[id(x,y)]? ans[link[id(x,y)]]=0,link[link[id(x,y)]]=id(x,y):ans[id(x,y)]=1;int tcnt=cnt;for (int i=1;i<=tcnt;i++) addnode(e[i].v,e[i].u);for (int i=1;i<=n*m;i++) if (ans[i]) dfs(i);int tot=0;for (int x=1;x<=n;x++)for (int y=1;y<=m;y++)tot+=ans[id(x,y)];printf("%d\n",tot);for (int x=1;x<=n;x++)for (int y=1;y<=m;y++)if (ans[id(x,y)])printf("%d %d\n",x,y);return 0;
}

【LOJ6033】棋盘游戏【二分图博弈】相关推荐

  1. BZOJ 1443 二分图博弈 网络流

    思路: 二分图博弈嘛 找到最大匹配的必须点 跑个网络流 前后DFS一遍 //By SiriusRen #include <queue> #include <cstdio> #i ...

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

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

  3. 2020CCPC(长春) - Combination Lock(二分图博弈)

    题目大意:给出一个密码锁,两个人一起玩游戏,给出初始的密码,规定: 每一次都可以转动一个位置的数字一个单位 不可以转动到已经出现过的数字 不可以转动到被 ban 掉的数字 无法转动的人视为失败,问谁能 ...

  4. 【NOI2011】兔兔与蛋蛋的游戏【二分图博弈】

    传送门 结论 不会有同一个棋子移动两次 反证法,对于第一个移动第二次的棋子 设两次移动之间(含)的移动的棋子为A1,A2,A3,--,AnA_1,A_2,A_3,--,A_nA1​,A2​,A3​,- ...

  5. 博弈论题表(好少~~~)

    bzoj2017:[Usaco2009 Nov]硬币游戏 *用了一小点思想的傻逼dp(记忆化搜索) bzoj1188:[HNOI2007]分裂游戏 **很神奇的把游戏拆分为子游戏的方法 bzoj102 ...

  6. Contest Record

    Contest 1135 at HZOI Problem A: 优美的棋 发现一个可以证明的规律就是了-- 忘记给<<运算的左边变量转化为long long类型了,结果挂了20分-- 以后 ...

  7. bzoj2437 [Noi2011]兔兔与蛋蛋

    二分图博弈果然都是一个套路,必经点必胜,非必经点必败, 但是肯定不能每走一步就重新建图判断必胜还是必败,那么我们可以这样:每走一步就把这个点删掉,然后find他原来的匹配,如果找不到,就说明他是必经点 ...

  8. NOI2010~NOI2018选做

    [NOI2010] [NOI2010]海拔 高度只需要0/1,所以一个合法方案就是一个割,平面图求最小割. [NOI2010]航空管制 反序拓扑排序,每次取出第一类限制最大的放置,这样做答案不会更劣. ...

  9. 一些有难度的网络流问题

    本质是线性规划 最小割建模 NOI2010 海拔 一个的网格,每跳变的两个方向都有一定数目的人流,每个格点都有海拔,一个人爬坡需要付出高度差的代价,下坡不付出代价,左下角高度为,右上角高度为,求安排其 ...

最新文章

  1. 小猿圈html5教程之canvas绘制线段方法
  2. PowerDesigner如何导出建表sql脚本(转)
  3. 微信小程序—day02
  4. 现代软件工程 作业 第一周博客作业
  5. 还在家隔离呢?没事写写这些程序吧!
  6. hadoop搭建之hadoop安装
  7. html横菜单中菜单均匀分布,html – 如何在flexbox中的行间均匀分布元素?
  8. 用Podman来代替Docker Desktop
  9. 面试常见的26个问题
  10. Python游戏嗷大喵快跑设计
  11. Python与OpenCV(二)——基于背景差分法的运动目标检测程序分析
  12. 孙溟㠭创作篆刻作品(稻)纪念袁隆平老先生
  13. 滞胀世代 (ZT) 作者:bystander
  14. 常用的excel公式备忘
  15. python的flask框架
  16. Ubuntu 16.04 LTS安装sogou输入法详解
  17. XX健康:预约管理-预约设置日历插件文件简单下载Excel文件解析Excel表数据批量导入
  18. RFID技术在固定资产管理中的作用
  19. 思科nexus虚拟交换之开机初始化配置(Nexus7K、Nexus5K等)
  20. xp系统怎样访问校园网服务器,有线校园网电脑连接教程

热门文章

  1. 她半年内举报了755篇问题论文,专挑中国“下手”?还牵扯到北大副校长.........
  2. 一个富二代仅凭“1+1”就压制了全世界的数学家两个世纪......
  3. 用MATLAB三步完成机器人搭建
  4. 不作死就不会死,盘点那些死于自己发明的发明家
  5. 渤海发现大油田,证券会提示风险,微博回应流量造假,刘国梁制定史上最严奖惩体系,这就是今天的大新闻。...
  6. 风靡全球的人工智能,如何赶上这班车?
  7. 重磅来袭,2018 年 6 月编程语言排行榜
  8. 姑娘,你为什么要编程?
  9. 计算机视觉招聘_INDEMIND|SLAM、计算机视觉、深度学习算法招聘(社招实习)
  10. 用linux命令通常做什么,如何知道你在 Linux 里最常使用的几个命令?