题目大意:n*m的棋盘,其中有些区域是禁区,两个人在棋盘上进行博弈,后手选择棋子的初始位置,然后先后手轮流将棋子往上下左右移动,走过的区域不能再走,问能否有一个位置使得后手必胜

Input

输入数据首先输入两个整数N,M,表示了迷宫的边长。 接下来N行,每行M个字符,描述了迷宫。

Output

若小AA能够赢得游戏,则输出一行"WIN",然后输出所有可以赢得游戏的起始位置,按行优先顺序输出 每行一个,否则输出一行"LOSE"(不包含引号)。

Sample Input

3 3
.##
...
#.#

Sample Output

2 3
3 2

HINT

对于100%的数据,有1≤n,m≤100。 
对于30%的数据,有1≤n,m≤5。

Source

JSOI2009Day2

完成二分图这章绝对有必要做的一题

思路:如果没有禁区,那这题就沦为了这题:http://hi.baidu.com/lov_zyf/item/04fa260e7b3ba41acc34eaff  [中山市选2009]谁能赢呢?

唔 分奇偶讨论就行,那有禁区怎么办?其实可以从上面那题收到启发,就是1*2的骨牌的覆盖问题,然后大白书二分图匹配那章那个经典的博弈也是解开这题的关键

显然如果棋盘能完全被1*2骨牌覆盖,那么后手必输,因为先手总能移动到骨牌的另一端,如果不能被完全覆盖呢?只要将棋子放在没被覆盖的那点就行了,先手第一步一定移动到一个骨牌里去,先后手交换

间二染色后,这个问题成了二分图匹配的问题,只要初始位置是一个未盖点,那么后手一定能沿着增光轨走下去,因此后手必胜

那么判断出胜负后接下来问题就是哪些位置可能成为初始位置,基于上面的讨论这个点一定是可能成为未盖点的点(因为二分图的最大匹配可能有很多种样子,虽然匹配数相同)

最直观的方法应该是:考虑一个点如果一定在最大匹配里(也就是不可能成为初始点)那么将这个点删除,其它边不变做一次匈牙利,看最大匹配数是否改变,但这是个显然超时的做法

于是我考虑一个y部的点时,保留之前做过的最短路,把这点标记掉,如果之前和y部这个点匹配的点能继续增广,也就是在最大匹配保持不变的情况下,这个点能和新的点匹配,那这个y部的点就是可有可无的了,也就是可以成为未盖点

------------------------------------------------------------------------------------------------------------

顺便做完后百度了下题解,发现做法真多!二分图那部边基本是相同的思路,考虑哪些点可能成为未盖点的时候有沿着增广轨DFS的,有网络流的,而且速度都比我快,果然还是too young

#include <stdio.h>

#include <iostream>

#include<queue>

#include <string.h>

#include <algorithm>

#define maxn 200000

#define maxm 1000005

#define inf 0x3f3f3f3f

using namespace std;

const int dx[10]={0,0,0,1,-1};

const int dy[10]={0,1,-1,0,0};

int next[maxn],head[maxn],now,point[maxn];

int match[maxn],x[maxn],y[maxn],mat[maxn];

bool visit[maxn],mark[maxn];

char ch[200][200];

void add(int x,int y)

{

next[++now]=head[x];

head[x]=now;

point[now]=y;

}

int dfs(int k)

{

for(int i=head[k];i;i=next[i])if(!visit[point[i]])

{

int u=point[i];

visit[u]=1;

if(dfs(match[u])||match[u]==-1)

{

match[u]=k;

mat[k]=u;

return 1;

}

}

return 0;

}

int main()

{

int n,m,u=0,v=0,flag=0;

scanf("%d%d",&n,&m);

for(int i=1;i<=n;i++)scanf("%s",ch[i]+1);

int fi=0;

for(int i=1;i<=n;i++)

{

fi^=1;

for(int j=fi+1;j<=m;j+=2)if(ch[i][j]=='.')

{

x[++u]=i*m+j;

for(int k=1;k<=4;k++)

{

int xx=i+dx[k],yy=j+dy[k];

if(ch[xx][yy]=='.')

{

add(i*m+j,xx*m+yy);

add(xx*m+yy,i*m+j);

}

}

}

}

fi=1;

for(int i=1;i<=n;i++)

{

fi^=1;

for(int j=fi+1;j<=m;j+=2)

if(ch[i][j]=='.')y[++v]=i*m+j;

}

memset(match,-1,sizeof(match));

for(int i=1;i<=u;i++)

{

memset(visit,0,sizeof(visit));

if(!dfs(x[i]))

{flag=1;mark[x[i]]=1;}

}

for(int i=1;i<=v;i++)

{

if(match[y[i]]==-1){mark[y[i]]=1;flag=1;}

else

{

memset(visit,0,sizeof(visit));

visit[y[i]]=1;

if(dfs(match[y[i]]))

{match[y[i]]=-1;mark[y[i]]=1;flag=1;}

}

}

for(int i=1;i<=v;i++)

{

memset(visit,0,sizeof(visit));

if(!dfs(y[i]))

{flag=1;mark[y[i]]=1;}

}

for(int i=1;i<=u;i++)

{

if(match[x[i]]==-1){mark[x[i]]=1;flag=1;}

else

{

memset(visit,0,sizeof(visit));

visit[x[i]]=1;

if(dfs(match[x[i]]))

{match[x[i]]=-1;mark[x[i]]=1;flag=1;}

}

}

if(flag==1)printf("WIN\n");else{printf("LOSE\n");return 0;}

for(int i=1;i<=n;i++)

{

for(int j=1;j<=m;j++)

{

if(mark[i*m+j])printf("%d %d\n",i,j);

}

}

return 0;

}

BZOJ:[JSOI2009]游戏Game【二分图匹配乱搞】的更多相关文章

  1. 【BZOJ1443】游戏(二分图匹配,博弈论)

    [BZOJ1443]游戏(二分图匹配,博弈论) 题面 BZOJ 题解 很明显的二分图博弈问题. 发现每次移动一定是从一个黑点到达一个白点,或者反过来. 所以可以对于棋盘进行染色然后连边. 考虑一下必胜 ...

  2. 【BZOJ4554】游戏(二分图匹配,网络流)

    [BZOJ4554]游戏(二分图匹配,网络流) 题解 Description 在2016年,佳缘姐姐喜欢上了一款游戏,叫做泡泡堂.简单的说,这个游戏就是在一张地图上放上若干个炸弹,看 是否能炸到对手, ...

  3. BZOJ_4554_[Tjoi2016&Heoi2016]游戏_二分图匹配

    BZOJ_4554_[Tjoi2016&Heoi2016]游戏_二分图匹配 Description 在2016年,佳缘姐姐喜欢上了一款游戏,叫做泡泡堂.简单的说,这个游戏就是在一张地图上放上若 ...

  4. BZOJ 1854: [Scoi2010]游戏(二分图匹配/并查集)

    题面: https://www.lydsy.com/JudgeOnline/problem.php?id=1854 题解: 1.二分图匹配: 首先我们发现每件装备只能在两种属性中选一种.因此,我们以每 ...

  5. BZOJ 1059 [ZJOI2007]矩阵游戏:二分图匹配

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1059 题意: 给你一个n*n的01矩阵. 你可以任意次地交换某两行或某两列. 问你是否可以 ...

  6. [SCOI2010]连续攻击游戏 BZOJ1854 二分图匹配

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

  7. BZOJ1854:游戏(二分图匹配)

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

  8. [BZOJ1059]:[ZJOI2007]矩阵游戏(二分图匹配)

    题目传送门 题目描述 小Q是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏——矩阵游戏.矩阵游戏在一个N×N黑白方阵进行(如同国际象棋一般,只是颜色是随意的).每次可以对该矩阵进行两种 ...

  9. BZOJ.3140.[HNOI2013]消毒(二分图匹配 匈牙利)

    题目链接 不难想到每次一定是切一片. 如果是平面,很容易想到直接做二分图匹配.对于3维的? 可以发现min(a,b,c)的最大值只有\(\sqrt[3]{n}≈17\),我们暴力枚举这一最小值代表的是 ...

随机推荐

  1. 关于 a 标签 jquery的trigger("click"),无法触发问题。

    这个问题的原因不是jquery的trigger("click"), 函数的问题, 而是 a标签之间要有其他子标签,要对这个子标签调用trigger("click" ...

  2. Java GUI 基础组件

    1.JLabel  标签 构造函数: JLabel() JLabel(String text) JLabel(String text,int align)     //第二个参数设置文本的对齐方式,常 ...

  3. CG Shader常用函数

    为了方便自己记忆,将常用的CG函数写于此 转载于 http://www.cppblog.com/lai3d/archive/2008/10/23/64889.html Name Syntax Desc ...

  4. canvas基础绘制-倒计时(上)

    效果: html: <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  5. ceph脚本-自动部署计算机节点

    依然还在加班中,最近确实忙的脚打后脑勺! 又花了些时间丰富ceph脚本,可以连带着自动部署计算机节点了. 这一部分内容是后加的.可以关注我的公众号获取更多的项目代码和讲解!波神与你同行哦,加油!!!

  6. 更新github上的代码

    昨晚熬夜写完了"git上传本地项目代码到github"的任务,早上来公司先把早上的工作完成后,抽点时间继续来继续更新文章 更新github上的代码 一.克隆代码 1.把大神的代码c ...

  7. java-基于泛型和反射机制的通用比较器实现

    一.前言 Java的比较器是用来对List集合进行排序用的,分为内部比较器和外部比较器两类 内部比较器:被排序的类要 implements Comparable 类,并实现compareTo方法. 外 ...

  8. 小程序request请求 POST请求参数传递不到后台

    wx.request({ url: 'https://xxx.com/xxxx.php', data: { 'jscode': code }, method: 'POST', header: { &q ...

  9. No-7.系统信息相关命令

    系统信息相关命令 本节内容主要是为了方便通过远程终端维护服务器时,查看服务器上当前 系统日期和时间 / 磁盘空间占用情况 / 程序执行情况 本小结学习的终端命令基本都是查询命令,通过这些命令对系统资源 ...

  10. excel数据比对,查找差异

    1.选中需比对的数据 2.开始->条件格式->突出显示单元格规则->重复值 3.选择唯一值,点击确定 4.结果展示 5.颜色标识的即:不同值