祝各位圣诞后快乐(逃)

题目传送门

分析:

首先棋盘上的路径构成的图是一张二分图

那么对于一个二分图,先求出最大匹配,先手如果走到关键匹配点,只要后手顺着匹配边走,由于不再会出现增广路径,所以走到最后先手就必败

所以Alice只要到非关键匹配点,Bob便一定会走到关键匹配点,然后Alice便必胜

于是求一下那些点是非关键匹配点就好了

真难想233

我好菜233

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue> #define maxn 500005
#define maxm 105
#define INF 0x3f3f3f3f using namespace std; inline long long getint()
{
long long num=,flag=;char c;
while((c=getchar())<''||c>'')if(c=='-')flag=-;
while(c>=''&&c<='')num=num*+c-,c=getchar();
return num*flag;
} int n,m;
int S,T;
int fir[maxn],nxt[maxn],to[maxn],cap[maxn],cnt;
int h[maxn],vis[maxn];
char s[maxm][maxm];
int ans[maxm][maxm]; inline void newnode(int u,int v,int w)
{to[++cnt]=v,nxt[cnt]=fir[u],fir[u]=cnt,cap[cnt]=w;}
inline void insert(int u,int v,int w)
{newnode(u,v,w),newnode(v,u,);} inline bool bfs()
{
memset(h,-,sizeof h);h[S]=;
queue<int>Q;Q.push(S);
while(!Q.empty())
{
int u=Q.front();Q.pop();
for(int i=fir[u];i;i=nxt[i])
if(!~h[to[i]]&&cap[i])h[to[i]]=h[u]+,Q.push(to[i]);
}
return ~h[T];
} inline int aug(int u,int flow)
{
if(u==T||!flow)return flow;
int used=;
for(int i=fir[u];i;i=nxt[i])
if(cap[i]&&h[to[i]]==h[u]+)
{
int delta=aug(to[i],min(flow-used,cap[i]));
cap[i]-=delta,cap[i^]+=delta,used+=delta;
if(used==flow)return flow;
}
if(!used)h[u]=-;
return used;
} inline int dinic()
{
int num=;
while(bfs())num+=aug(S,INF);
return num;
} inline void dfs(int u)
{
vis[u]=;
for(int i=fir[u];i;i=nxt[i])if(!vis[to[i]]&&cap[i])dfs(to[i]);
} inline void dfs2(int u)
{
vis[u]=;
for(int i=fir[u];i;i=nxt[i])if(!vis[to[i]]&&cap[i^])dfs2(to[i]);
} inline int getid(int i,int j){return i*m+j-m;} int main()
{
n=getint(),m=getint();int num=;
for(int i=;i<=n;i++)scanf("%s",s[i]+);
S=n*m+,T=S+;cnt=;
for(int i=;i<=n;i++)for(int j=;j<=m;j++)
{
if(((i+j)&)&&s[i][j]=='.')
{
insert(S,getid(i,j),);
if(s[i-][j]=='.')insert(getid(i,j),getid(i-,j),INF);
if(s[i+][j]=='.')insert(getid(i,j),getid(i+,j),INF);
if(s[i][j-]=='.')insert(getid(i,j),getid(i,j-),INF);
if(s[i][j+]=='.')insert(getid(i,j),getid(i,j+),INF);
}
if(!((i+j)&)&&s[i][j]=='.')insert(getid(i,j),T,);
}
dinic();
dfs(S);
for(int i=;i<=n;i++)for(int j=;j<=m;j++)
if(((i+j)&)&&s[i][j]=='.'&&vis[getid(i,j)])ans[i][j]=,num++;
memset(vis,,sizeof vis);
dfs2(T);
for(int i=;i<=n;i++)for(int j=;j<=m;j++)
if(!((i+j)&)&&s[i][j]=='.'&&vis[getid(i,j)])ans[i][j]=,num++;
printf("%d\n",num);
for(int i=;i<=n;i++)for(int j=;j<=m;j++)
if(ans[i][j])printf("%d %d\n",i,j);
}

「雅礼集训 2017 Day2」棋盘游戏的更多相关文章

  1. loj#6033. 「雅礼集训 2017 Day2」棋盘游戏(二分图博弈)

    题意 链接 Sol 第一次做在二分图上博弈的题..感觉思路真是清奇.. 首先将图黑白染色. 对于某个点,若它一定在最大匹配上,那么Bob必胜.因为Bob可以一直沿着匹配边都,Alice只能走非匹配边. ...

  2. [LOJ#6033]. 「雅礼集训 2017 Day2」棋盘游戏[二分图博弈、匈牙利算法]

    题意 题目链接 分析 二分图博弈经典模型,首先将棋盘二分图染色. 考虑在某个最大匹配中: 如果存在完美匹配则先手必败,因为先手选定的任何一个起点都在完美匹配中,而后手则只需要走这个点的匹配点,然后先手 ...

  3. LOJ6033「雅礼集训 2017 Day2」棋盘游戏 (博弈论,二分图,匈牙利算法)

    什么神仙思路啊-- 看到棋盘就去想二分图.(smg啊)(其实是校内模拟赛有基本一样的题,只不过直接给了个二分图) 看到二分图就去想最大匹配.(我怎么想偶环的性质去了) (以下内容摘自这里) 这个二分图 ...

  4. 「雅礼集训 2017 Day2」解题报告

    「雅礼集训 2017 Day2」水箱 我怎么知道这种题目都能构造树形结构. 根据高度构造一棵树,在树上倍增找到最大的小于约束条件高度的隔板,开一个 \(vector\) 记录一下,然后对于每个 \(v ...

  5. #6034. 「雅礼集训 2017 Day2」线段游戏 李超树

    #6034. 「雅礼集训 2017 Day2」线段游戏 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统 ...

  6. 【loj6034】「雅礼集训 2017 Day2」线段游戏

    #6034. 「雅礼集训 2017 Day2」线段游戏 内存限制:256 MiB 时间限制:1000 ms 标准输入输出 题目类型:传统 评测方式:Special Judge 上传者: 匿名 题目描述 ...

  7. loj#6032. 「雅礼集训 2017 Day2」水箱(并查集 贪心 扫描线)

    题意 链接 Sol 神仙题+神仙做法%%%%%%%% 我再来复述一遍.. 首先按照\(y\)坐标排序,然后维护一个扫描线从低处往高处考虑. 一个连通块的内状态使用两个变量即可维护\(ans\)表示联通 ...

  8. LOJ#6032. 「雅礼集训 2017 Day2」水箱

    传送门 首先可以有一个平方复杂度的 \(DP\) 设 \(f_{i,j}\) 表示前面 \(i\) 个小格,高度为 \(j\) 的最大答案 令 \(h_i\) 表示隔板 \(i\) 的高度 当 \(j ...

  9. 「雅礼集训 2017 Day2」水箱

    题目链接 题意分析 我们用\(f[i][j]\)表示当前到达第\(i\)个位置水位高度为\(j\)的答案 如果那么\(h[i]\)为\(i\)和\(i+1\)之间的支柱高度 那么如果\(j≤h[i]\ ...

随机推荐

  1. dotnet 如何在 Mock 模拟 Func 判断调用次数

    在 dotnet 程序有很好用的 Mock 框架,可以用来模拟各种接口和抽象类,可以用来测试某个注入接口的被调用次数和被调用时传入参数.本文告诉大家如何在 Mock 里面模拟一个 Func 同时模拟返 ...

  2. dotnet 数组自动转基类数组提示 Co-variant array conversion 是什么问题

    在 C# 的语法,可以提供自动将某个类的数组自动转这个类的基类数组的方法,但是这样的转换在 Resharper 会提示 Co-variant array conversion 这是什么问题? 在 C# ...

  3. HDU - 4289 Control (Dinic)

    You, the head of Department of Security, recently received a top-secret information that a group of ...

  4. python 多线程两种实现方式,Python多线程下的_strptime问题,

    python 多线程两种实现方式 原创 Linux操作系统 作者:杨奇龙 时间:2014-06-08 20:24:26  44021  0 目前python 提供了几种多线程实现方式 thread,t ...

  5. QString 转换为 char *

    一.QString 转换为 char * 将 QString 转 char *,需要用到 QByteArray 类,QByteArray 类的说明详见 Qt 帮助文档. 因为 char * 最后都有一 ...

  6. JMeter数据库测试计划

    在系统上安装数据库服务器之后. 按着这些次序: 创建名为testdb的数据库. 创建表 - tb_user. 将记录插入到tb_user表中. 下图显示了创建的数据库及其记录. 注意:您需要将相应的J ...

  7. The Struts dispatcher cannot be found异常的解决方法

    系统错误:HTTP Status 500 异常信息:The Struts dispatcher cannot be found.  This is usually caused by using St ...

  8. 洛谷$P2572\ [SCOI2010]$ 序列操作 线段树/珂朵莉树

    正解:线段树/珂朵莉树 解题报告: 传送门$w$ 本来是想写线段树的,,,然后神仙$tt$跟我港可以用珂朵莉所以决定顺便学下珂朵莉趴$QwQ$ 还是先写线段树做法$QwQ$? 操作一二三四都很$eas ...

  9. ECMAScript新语法、特性总结

    前言 从2015年的ES6开始,JavaScript的语言标准每年都在更新,其中尤其以ES6的力度之大,到现在ES10已经发布,这里总结一下新语法. 参考:阮一峰 ECMAScript 6 教程 .E ...

  10. Wireshark抓包,带你快速入门

    前言 关于抓包我们平时使用的最多的可能就是Chrome浏览器自带的Network面板了(浏览器上F12就会弹出来).另外还有一大部分人使用Fiddler,Fiddler也是一款非常优秀的抓包工具.但是 ...