首先对网格染色,发现是而二分图。

那么即在二分图上选一个起点走过的点无法再走,最后无路可走就输了。

如果起点必在最大匹配中,先手必赢。
如果起点不一定在最大匹配中(包括不可能在),后手必赢。网上有解释。
因为写二分图不怎么熟练,所以还是用网络流吧。
找的就是可行的和不在最大匹配中点。建边要用单向边。
从源点和汇点开始Dfs。假如从左边开始那么先扫到右边后又扫到左边。那么那个点就是可行点。
 #include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int Maxn=;
const int Inf=0x3f3f3f3f;
int n,m,S,T,g[][],Color[Maxn],head[Maxn],Level[Maxn],Q[Maxn],u,v,cnt,cur[Maxn],Ans[Maxn],ans;
bool vis[Maxn];
struct Node{int to,next,w;}edge[];
const int dx[]={,,,-};
const int dy[]={,-,,};
inline int Id(int x,int y) {return (x-)*m+y;}
inline bool Check(int u,int v) {return ((u<=n&&u>=)&&(v<=m&&v>=));}
inline int Min(int x,int y) {return x>y?y:x;}
inline void ADD(int u,int v,int w)
{edge[cnt].to=v;edge[cnt].next=head[u];edge[cnt].w=w;head[u]=cnt++;}
inline void Add(int u,int v,int w) {ADD(u,v,w);ADD(v,u,);}
bool Bfs()
{
memset(Level,-,sizeof(Level));
Level[S]=; Q[]=S; int l=,r=;
while (l<=r)
{
int u=Q[l++];
for (int i=head[u];i!=-;i=edge[i].next)
if (Level[edge[i].to]==- && edge[i].w>)
{
Level[edge[i].to]=Level[u]+;
Q[++r]=edge[i].to;
}
}
if (Level[T]==-) return false;
return true;
}
int Find(int u,int low)
{
if (u==T || low==) return low;
int cap=;
for (int i=cur[u];i!=-;i=edge[i].next)
if (edge[i].w> && Level[edge[i].to]==Level[u]+)
{
int tmp=Find(edge[i].to,Min(low,edge[i].w));
if (tmp==) continue;
low-=tmp,cap+=tmp;
edge[i].w-=tmp,edge[i^].w+=tmp;
if (edge[i].w>) cur[u]=i;
}
if (cap) return cap;
Level[u]=-;
return ;
}
void Dfs(int u,int c)
{
vis[u]=true;
if (Color[u]==c && u!=S && u!=T) Ans[++ans]=u;
for (int i=head[u];i!=-;i=edge[i].next)
if (edge[i].w==c && !vis[edge[i].to]) Dfs(edge[i].to,c);
} void Get_Ans()
{
memset(vis,false,sizeof(vis)),Dfs(S,);
memset(vis,false,sizeof(vis)),Dfs(T,);
}
int main()
{
// freopen("c.in","r",stdin);
// freopen("c.out","w",stdout);
scanf("%d%d",&n,&m);
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
{
char ch=getchar();
while (ch!='.' && ch!='#') ch=getchar();
if (ch=='.') g[i][j]=;
if (ch=='#') g[i][j]=;
}
S=,T=Id(n,m)+;
memset(head,-,sizeof(head));
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
if (g[i][j])
{
if (!((i+j)&))
{
Add(S,Id(i,j),);
Color[Id(i,j)]=true;
for (int k=;k<;k++)
{
int u=i+dx[k],v=j+dy[k];
if (!Check(u,v)) continue;
if (g[u][v]) Add(Id(i,j),Id(u,v),);
}
}
else Add(Id(i,j),T,);
}
// for (int i=0;i<cnt;i++) printf("%d ",edge[i].to); puts("");
// for (int i=0;i<cnt;i++) printf("%d ",edge[i].w);puts("");
// for (int i=1;i<cnt;i++) printf("%d ",edge[i].next);puts("");
while (Bfs())
{
for (int i=S;i<=T;i++) cur[i]=head[i];
Find(S,Inf);
}
Get_Ans();
if (!ans) puts("LOSE"); else
{
puts("WIN");
sort(Ans+,Ans+ans+);
for (int i=;i<=ans;i++) printf("%d %d\n",(Ans[i]-)/m+,(Ans[i]-)%m+);
}
// if ()
return ;
}

C++

BZOJ 1433 二分图上的博弈的更多相关文章

  1. [ZJOI2009]假期的宿舍 BZOJ 1433 二分图匹配

    题目描述 学校放假了 · · · · · · 有些同学回家了,而有些同学则有以前的好朋友来探访,那么住宿就是一个问题.比如 A 和 B 都是学校的学生,A 要回家,而 C 来看B,C 与 A 不认识. ...

  2. bzoj 1433 二分图匹配

    裸地匈牙利或者最大流,直接匹配就行了 需要注意的是(我就没注意细节WA了好多次...) 每个人和自己之间的边是0,但是应该是1 不是在校生是没有床的.... /******************** ...

  3. BZOJ - 2744 朋友圈 (二分图上的最大团)

    [题目大意] 在很久很久以前,曾经有两个国家和睦相处,无忧无虑的生活着.一年一度的评比大会开始了,作为和平的两国,一个朋友圈数量最多的永远都是最值得他人的尊敬,所以现在就是需要你求朋友圈的最大数目.两 ...

  4. [BZOJ 4025]二分图(线段树分治+带边权并查集)

    [BZOJ 4025]二分图(线段树分治+带边权并查集) 题面 给出一个n个点m条边的图,每条边会在时间s到t出现,问每个时间的图是否为一个二分图 \(n,m,\max(t_i) \leq 10^5\ ...

  5. bzoj 4025 二分图 分治+并查集/LCT

    bzoj 4025 二分图 [题目大意] 有n个点m条边,边会在start时刻出现在end时刻消失,求对于每一段时间,该图是不是一个二分图. 判断二分图的一个简单的方法:是否存在奇环 若存在奇环,就不 ...

  6. Bzoj 4147: [AMPPZ2014]Euclidean Nim(博弈)

    4147: [AMPPZ2014]Euclidean Nim Time Limit: 1 Sec Memory Limit: 256 MB Description Euclid和Pythagoras在 ...

  7. bzoj 1443 二分图博弈

    这种两个人轮流走,不能走 走过的格子的大都是二分图博弈... #include<bits/stdc++.h> #define LL long long #define fi first # ...

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

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

  9. BZOJ 1059 & 二分图匹配

    题意: 判断一个黑白染色的棋盘能否通过交换行或列使对角线上都是黑色. SOL: 真是有点醉...这种问题要么很神要么很水...第一眼感觉很水但就是不造怎么做...想了10分钟怎么感觉就是判断个数够不够 ...

随机推荐

  1. LR java Vuser 相关依赖JAR包,配置文件处置方法

    JAR包,配置文件依赖有两种处理方法 1.放到工程文件夹下(lr脚本目录),不支持负载机调用 2.F4  classpath设置加载jar包和配置文件的整个文件夹,麻烦些,但支持负载机调用(与http ...

  2. javascript 面向对象(转)

    1.使用[]调用对象的属性和方法 function User() { this.age = 21; this.sex = "男?"; } var user = new User() ...

  3. Xcode7中,如何新建category分类

    易忘,所以留存: 1, 2, 3, 结果如下: 补充: http://tech.meituan.com/DiveIntoCategory.html

  4. Hadoop 2.4.x集群安装配置问题总结

    配置文件:/etc/profile export JAVA_HOME=/usr/java/latest export HADOOP_PREFIX=/opt/hadoop-2.4.1 export HA ...

  5. 如何修改mysql用户名和密码

    如何修改mysql用户名和密码   以修改mysql的root密码为例修改的三种方法 方法1: 用SET PASSWORD命令 mysql>SET PASSWORD FOR 'root'@'lo ...

  6. Hadoop简介

    原来:计算效率低 现在:成本降低,能用PC机,就不用大型机和高端存储了:软件容错硬件故障视为常态,通过软件保证可靠性:简化并行分布式计算,无需控制节点同步和数据交换,但是谷歌只发表了相关技术论文,没有 ...

  7. SQL疑难杂症【4 】大量数据查询的时候避免子查询

    前几天发现系统变得很慢,在Profiler里面发现有的SQL执行了几十秒才返回结果,当时的SQL如下: 可以看得出来,在652行用了子查询,恰巧目标表(QS_WIP)中的记录数为100000000+, ...

  8. HTTP协议的头信息详解

    转载地址:http://blog.csdn.net/guoguo1980/article/details/2649658 HTTP(HyperTextTransferProtocol)是超文本传输协议 ...

  9. unittest框架介绍

    1.test fixture(测试框架) 测试准备前要做的工作和测试执行完成后要做的工作,例如测试前需要把数据初始化,测试完成后需要把测试环境中需要关的东西都关掉.主要包括setUp()和tearDo ...

  10. 【转】CentOS 6.5安装pyspider过程记录

    原文地址:http://blog.sina.com.cn/s/blog_48c95a190102wczx.html 1.根据pyspider官方推荐的安装方法,使用pip命令直接安装pyspider ...