祝各位圣诞后快乐(逃)

题目传送门

分析:

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

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

所以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. 【38.63%】【hdu 3047】Zjnu Stadium

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s) ...

  2. onload事件属性,JQ中的load,ready方法

    onload事件属性,JQ中的load,ready方法 前言 页面中的很多操作,需要我们在所需资源下载完成后,才可以进行操作,而资源没有及时下载,我们进行操作的话,是会报错.因此我们需要熟练掌握哪些事 ...

  3. vue中的computed和watch区别

    在vue.js官方文档中看到computed和watch获取全名的一个例子: var var vm = new Vue({ el: '#demo', data: { firstName: 'Foo', ...

  4. 使用Glide加载圆角图片

    //设置图片圆角角度 RoundedCorners roundedCorners= new RoundedCorners(6); //通过RequestOptions扩展功能,override采样率, ...

  5. 转:EBS-自动获取/创建CCID

    DECLARE l_ccid NUMBER; l_msg ); l_chart_of_account_id NUMBER; l_set_of_book_id NUMBER; BEGIN l_set_o ...

  6. 【Kubernetes】部署K8s-dashboard v1.10.1

    一.官方kubernetes-dashboard.yaml简介 ①首先认识一下官方的kubernetes-dashboard.yaml,我们先下载: https://github.com/kubern ...

  7. 本地安装配置Gradle及IDEA使用本地Gradle

    一.下载Gradle   下载地址:http://services.gradle.org/distributions/   下载版本的bin.zip 二.配置环境变量 三.验证   在cmd模式下查看 ...

  8. context:component-scan 和 mvc:annotation-driven

    前言 Spring MVC 框架提供了几种不同的配置元素来帮助和指示 Spring 容器管理以及注入 bean . 常用的几个 XML 配置是 context:component-scan mvc:a ...

  9. 网络状态诊断工具——netstat命令

    netstat命令可以用来查询整个系统的网络状态.百度百科的定义如下: Netstat的定义是: Netstat是在内核中访问网络连接状态及其相关信息的程序,它能提供TCP连接,TCP和UDP监听,进 ...

  10. CSP201903-2二十四点

    如图所示先处理乘号和除号,再处理加减. #include<bits/stdc++.h> using namespace std; ];int main(){ int n; cin>& ...