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

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

如果起点必在最大匹配中,先手必赢。
如果起点不一定在最大匹配中(包括不可能在),后手必赢。网上有解释。
因为写二分图不怎么熟练,所以还是用网络流吧。
找的就是可行的和不在最大匹配中点。建边要用单向边。
从源点和汇点开始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. HTML5的数据自动补齐功能

    使用datalist元素,HTML5允许使用一组数据来生成自动补齐功能,现在你不需要使用第三方js代码或者类库啦! <input name="frameworks" list ...

  2. 20160330001 调用及触发Office Outlook 约会

    using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using Sy ...

  3. mac攻略(三) -- apache站点配置

    Mac OS X 中默认有两个目录可以直接运行你的 Web 程序, 一个是系统级的 Web 根目录:/Library/WebServer/Documents/ 此根目录我们平常使用地址http://l ...

  4. laravel框架总结(五) -- 服务提供者(提及契约Contracts)

    首先理解两个概念 1.契约:一组定义了框架核心服务的接口 2.服务提供者:所有 Laravel 应用程序启动的中心所在. 包括你自己的应用程序,以及所有的 Laravel 核心服务,都是通过服务提供者 ...

  5. 运用C#生成docx格式的报表

    这几天在北京做一个大桥的监测系统的项目,涉及到一个功能,那就是采集数据,处理后,希望能自动生成一个报表,只需要在一个模板的基础上加几个数就可以了,但因为希望生成的是.docx格式的word2007/2 ...

  6. SVN错误及处理

    SVN无法读取current修复方法 Can't read file : End of file found 文件:repository/db/txn_current.repository/db/cu ...

  7. angular之控制器(0)

    一.控制器的含义 在angularJS中,controlle是一个javascript函数/类,用于操作作用域中,各个对象的初始状态以及相应的行为 二.控制器的作用 1. 控制 AngularJS 应 ...

  8. Android TextView自动换行文字排版参差不齐的原因

    今天项目没什么进展,公司后台出问题了.看了下刚刚学习Android时的笔记,发现TextView会自动换行,而且排版文字参差不齐.查了下资料,总结原因如下: 1.半角字符与全角字符混乱所致:这种情况一 ...

  9. Ggoogle Protocol Buffer的使用 (基于C++语言)

    首先说明的是Protocol Buffle是灵活高效的.它的一个很好的优点(很重要的,我认为)就是后向兼容性--当我们扩展了了.proto文件后,我们照样可以用它来读取之前生成的文件. 之前已经写了关 ...

  10. PHP 小方法之 计算两个时间戳之间相差的日时分秒

    if(! function_exists ('timediff') ) { function timediff($begin_time,$end_time){ if($begin_time < ...