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

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

如果起点必在最大匹配中,先手必赢。
如果起点不一定在最大匹配中(包括不可能在),后手必赢。网上有解释。
因为写二分图不怎么熟练,所以还是用网络流吧。
找的就是可行的和不在最大匹配中点。建边要用单向边。
从源点和汇点开始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. 异常问题解决Error:Execution failed for task ':app:processDebugManifest'

    Error:Execution failed for task ':app:processDebugManifest' www.MyException.Cn  网友分享于:2015-12-28  浏览 ...

  2. java 字符串split有很多坑,使用时请小心!!

    System.out.println(":ab:cd:ef::".split(":").length);//末尾分隔符全部忽略 System.out.print ...

  3. 有限状态机(Python)

    有限状态机(Finite-state machine, FSM),又称有限状态自动机,简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型.FSM是一种算法思想,简单而言,有限状 ...

  4. MySQL安装(转)

    本文介绍MySQL的安装 可以单独阅读,也可以作为PHP环境搭建的一部分 PHP完整配置信息请参考 http://www.cnblogs.com/azhe-style/articles/php_env ...

  5. Java 中的 static 使用之静态变量

    大家都知道,我们可以基于一个类创建多个该类的对象,每个对象都拥有自己的成员,互相独立.然而在某些时候,我们更希望该类所有的对象共享同一个成员.此时就是 static 大显身手的时候了!! Java 中 ...

  6. 剑指offer一:二维数组中的查找

    题目: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 思路: 这是一个顺序二维 ...

  7. Java线程中yield与join方法的区别

    长期以来,多线程问题颇为受到面试官的青睐.虽然我个人认为我们当中很少有人能真正获得机会开发复杂的多线程应用(在过去的七年中,我得到了一个机会),但是理解多线程对增加你的信心很有用.之前,我讨论了一个w ...

  8. oracle 之索引,同义词 ,关键词,视图 ,存储过程,函数,触发器

    --创建索引 关键词 index create[unique] index index_name on table_name(column_name [,column_name…]) [tablesp ...

  9. myeclipse/eclipse没有Project Facets的解决方法

    http://www.cnblogs.com/jerome-rong/archive/2012/12/18/2822783.html 经常在eclipse中导入web项目时,出现转不了项目类型的问题, ...

  10. miniui设置边框的方法

    if (field == "loginname") { if (record._id == 2) { e.cellHtml = ""; e.cellStyle ...