loj#6033. 「雅礼集训 2017 Day2」棋盘游戏(二分图博弈)
题意
Sol
第一次做在二分图上博弈的题。。感觉思路真是清奇。。
首先将图黑白染色。
对于某个点,若它一定在最大匹配上,那么Bob必胜。因为Bob可以一直沿着匹配边都,Alice只能走非匹配边。到最后一定是Alice不能移动。
否则Alice必胜。这个我不会证,但是又举不出反例来qwq。手玩了几个数据发现Alice总会有一种方法走某个非匹配边干掉Bob。
那么如何找不一定在最大匹配上的点呢?首先求出一个最大匹配,结论是从所有不在最大匹配上的点开始dfs,通过交叉边(目标点的匹配边)走到点都是不一定在最大匹配上的点。(总有一种方案使这个点成为最大匹配)
然后直接匈牙利就行了
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int MAXN = 1001, INF = 1e9 + 7, mod = 998244353;
template <typename A, typename B> inline bool chmin(A &a, B b){if(a > b) {a = b; return 1;} return 0;}
template <typename A, typename B> inline bool chmax(A &a, B b){if(a < b) {a = b; return 1;} return 0;}
template <typename A, typename B> inline LL add(A x, B y) {if(x + y < 0) return x + y + mod; return x + y >= mod ? x + y - mod : x + y;}
template <typename A, typename B> inline void add2(A &x, B y) {if(x + y < 0) x = x + y + mod; else x = (x + y >= mod ? x + y - mod : x + y);}
template <typename A, typename B> inline LL mul(A x, B y) {return 1ll * x * y % mod;}
template <typename A, typename B> inline void mul2(A &x, B y) {x = (1ll * x * y % mod + mod) % mod;}
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, M;
char s[MAXN][MAXN];
vector<int> v[MAXN * MAXN];
void AE(int x, int y) {
v[x].push_back(y); v[y].push_back(x);
}
int vis[MAXN * MAXN], link[MAXN * MAXN], tag[MAXN * MAXN], times;
int id(int x, int y) {
return (x - 1) * M + y;
}
bool Aug(int x) {
for(auto &to : v[x]) {
if(vis[to] == times) continue;
vis[to] = times;//tag
if(!link[to] || Aug(link[to]))
{link[to] = x; link[x] = to; return 1;}
}
return 0;
}
void dfs(int x) {
tag[x] = 1;
for(auto &to : v[x]) if(!tag[link[to]]) dfs(link[to]);
}
int main() {
N = read(); M = read();
for(int i = 1; i <= N; i++) scanf("%s", s[i] + 1);
for(int i = 1; i <= N; i++)
for(int j = 1; j <= M; j++)
if(s[i][j] == '.') {
if(i < N && s[i + 1][j] == '.') AE(id(i, j), id(i + 1, j));
if(j < M && s[i][j + 1] == '.') AE(id(i, j), id(i, j + 1));
}
for(int i = 1; i <= N; i++)
for(int j = 1; j <= M; j++)
if(((i + j) & 1) && s[i][j] == '.')
times++, Aug(id(i, j));
for(int i = 1; i <= N; i++)
for(int j = 1; j <= M; j++)
if(s[i][j] == '.' && !link[id(i, j)] && !tag[id(i, j)])
dfs(id(i, j));
int ans = 0;
for(int i = 1; i <= N; i++)
for(int j = 1; j <= M; j++)
if(tag[id(i, j)]) ans++;
cout << ans << '\n';
for(int i = 1; i <= N; i++)
for(int j = 1; j <= M; j++)
if(tag[id(i, j)]) cout << i << ' ' << j << '\n';
return 0;
}
loj#6033. 「雅礼集训 2017 Day2」棋盘游戏(二分图博弈)的更多相关文章
- [LOJ#6033]. 「雅礼集训 2017 Day2」棋盘游戏[二分图博弈、匈牙利算法]
题意 题目链接 分析 二分图博弈经典模型,首先将棋盘二分图染色. 考虑在某个最大匹配中: 如果存在完美匹配则先手必败,因为先手选定的任何一个起点都在完美匹配中,而后手则只需要走这个点的匹配点,然后先手 ...
- loj#6032. 「雅礼集训 2017 Day2」水箱(并查集 贪心 扫描线)
题意 链接 Sol 神仙题+神仙做法%%%%%%%% 我再来复述一遍.. 首先按照\(y\)坐标排序,然后维护一个扫描线从低处往高处考虑. 一个连通块的内状态使用两个变量即可维护\(ans\)表示联通 ...
- LOJ#6032. 「雅礼集训 2017 Day2」水箱
传送门 首先可以有一个平方复杂度的 \(DP\) 设 \(f_{i,j}\) 表示前面 \(i\) 个小格,高度为 \(j\) 的最大答案 令 \(h_i\) 表示隔板 \(i\) 的高度 当 \(j ...
- loj #6032. 「雅礼集训 2017 Day2」水箱 线段树优化DP转移
$ \color{#0066ff}{ 题目描述 }$ 给出一个长度为 \(n\) 宽度为 \(1\) ,高度无限的水箱,有 \(n-1\) 个挡板将其分为 \(n\) 个 \(1 - 1\) 的小格, ...
- loj#6034 「雅礼集训 2017 Day2」线段游戏
分析 区间李超树板子题 代码 #include<bits/stdc++.h> using namespace std; #define db double const int inf = ...
- [LOJ#6044]. 「雅礼集训 2017 Day8」共[二分图、prufer序列]
题意 题目链接 分析 钦定 \(k\) 个点作为深度为奇数的点,有 \(\binom{n-1}{k-1}\) 种方案. 将树黑白染色,这张完全二分图的生成树的个数就是我们钦定 \(k\) 个点之后合法 ...
- LOJ6033「雅礼集训 2017 Day2」棋盘游戏 (博弈论,二分图,匈牙利算法)
什么神仙思路啊-- 看到棋盘就去想二分图.(smg啊)(其实是校内模拟赛有基本一样的题,只不过直接给了个二分图) 看到二分图就去想最大匹配.(我怎么想偶环的性质去了) (以下内容摘自这里) 这个二分图 ...
- 「雅礼集训 2017 Day2」棋盘游戏
祝各位圣诞后快乐(逃) 题目传送门 分析: 首先棋盘上的路径构成的图是一张二分图 那么对于一个二分图,先求出最大匹配,先手如果走到关键匹配点,只要后手顺着匹配边走,由于不再会出现增广路径,所以走到最后 ...
- 「雅礼集训 2017 Day2」解题报告
「雅礼集训 2017 Day2」水箱 我怎么知道这种题目都能构造树形结构. 根据高度构造一棵树,在树上倍增找到最大的小于约束条件高度的隔板,开一个 \(vector\) 记录一下,然后对于每个 \(v ...
随机推荐
- 微信小程序的概要
微信小程序的概要 学习小程序要了解一下什么事小程序,小程序开发前需要做哪些准备,微信小程序开发工具的使用,小程序中的目录结构解析,视图和渲染,事件. 小程序的配置详解,小程序的生命周期与app对象的使 ...
- 【MySQL】percona-toolkit工具包
[说明] percona-toolkit工具包同percona-xtrabackup一样都是用Perl写的工具包,percona-toolkit工具包是一组高级的管理mysql的工具包集,可以用来执行 ...
- Ubuntu 18.04安装配置pure-ftpd解决中文乱码问题
之前用的是vsftpd配置ftp服务器,前面用的挺好,没什么问题,但是后面接收设备上传的文件夹时发现了一个大坑,当设备上传的文件夹名字中包含中文时,在Linux上显示的是乱码...各种转码都不行,折腾 ...
- Docker 网络背后的原理探索
本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫. 知其然而不知其 ...
- 一看看懂Protocol Buffer(协议篇)
前言 由于笔者业团队的业务对即时通讯服务有很大的依赖,春节结束后的第一天,红包没到,产品同学先到了,产品同学和我说要做一款IM,看到需求文档后和设计图后笔者大吃一斤 这不就是一个翻版的web qq吗? ...
- mongo 更新字段值,若不存在则自动创建
查询语句 db.getCollection("A表").update( { "id":{$eq:11} } ,{ $set:{"a" ...
- Day2----Python学习之路笔记(2)
学习路线: Day1 Day2 Day3 Day4 Day5 ...待续 一.简单回顾一下昨天的内容 1. 昨天了解到了一些编码的知识 1.1. 我们写好的.py文件头没有加# -*- coding: ...
- 微信小程序注册60s倒计时功能 使用JS实现注册60s倒计时功能
微信小程序+WEB使用JS实现注册[60s]倒计时功能开发步骤: 1.wxml页面代码: <text>绑定手机</text> <form bindsubmit=" ...
- Magicodes.NET框架之路——让Magicodes.NET帮你编写代码
时间总是过得很快,而我几乎没有时间来安安静静的写博客和完善文档.不过总算是框架在一直前进,而我的计划是在今年年底(公历)前,让此框架成熟稳定. 在很长一段时间里,我尝试了很多我之前没有接触的技术或者没 ...
- 搭建企业级PPTP服务器
本文收录在企业项目实战系列 一.VPN 介绍 1.介绍 虚拟私人网络(英语:Virtual Private Network,缩写为VPN)是一种常用于连接中.大型企业或团体与团体间的私人网络的通讯方法 ...