【题解】宫廷守卫 [P1263]
【题解】宫廷守卫 [P1263]
传送门:宫廷守卫 \([P1263]\)
【题目描述】
给出一个 \(n*m\) 的方格图,分别用整数 \(0,1,2\) 表示空地、陷阱、墙,空地上可以放置守卫,如果两个守卫在同一行或同一列且他们之间没有墙的阻挡,那么他们就会互相看见。求最多可以放置多少个守卫使得他们互相无法看见对方,并输出其中一种方案。
【样例】
样例输入:
3 4
2 0 0 0
2 2 2 1
0 1 0 2
样例输出:
2
1 2
3 3
【数据范围】
\(100 \%:\) \(1 \leqslant n,m \leqslant 200\)
【分析】
如果没有墙的限制,那就是一个果的二分图套路题(車的放置),将每一行看作左点,每一列看作右点,对于没有陷阱的点(空地),将其所在行与其所在列连边,跑一遍二分图最大匹配即可。
墙的存在使得每一行、每一列都分裂成了若干部分,且每一部分都是独立存在、互不干涉的,因此可以把每一部分都视作一个点,例如样例:
第三列 被 墙\((2,3)\) 分为了上下两个部分,上面是否放守卫与下面能否放守卫没有任何关联,同理下面也如此。
剩余部分与 車的放置 相同。
【Code】
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<vector>
#define Re register int
using namespace std;
const int N=203,M=80003;
struct QAQ{int to,next;}a[M<<1];
int n,m,o,n1,n2,ans,pan[N*N*2],head[N*N*2],match[N*N*2],A[N][N],idh[N][N],idz[N][N];
inline void add(Re x,Re y){a[++o].to=y,a[o].next=head[x],head[x]=o;}
inline void in(Re &x){
int f=0;x=0;char c=getchar();
while(c<'0'||c>'9')f|=c=='-',c=getchar();
while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
x=f?-x:x;
}
inline int dfs(Re x){//匈牙利算法
for(Re i=head[x],to;i;i=a[i].next)
if(!pan[to=a[i].to]){
pan[to]=1;
if(!match[to]||dfs(match[to])){
match[to]=x;return 1;
}
}
return 0;
}
int main(){
// freopen("guard.in","r",stdin);
// freopen("guard.out","w",stdout);
in(n),in(m);
for(Re i=1;i<=n;++i)
for(Re j=1;j<=m;++j)
in(A[i][j]);
for(Re i=1;i<=n;++i)A[i][0]=2;//预处理边界
for(Re i=1;i<=m;++i)A[0][i]=2;
for(Re i=1;i<=n;++i)//处理每一行
for(Re j=1;j<=m;++j)
if(A[i][j]<2)//不是墙,需要建点
if(A[i][j-1]>1)idh[i][j]=++n1;//前面是墙,新开一部分
else idh[i][j]=idh[i][j-1];//前面不是墙,与其算作一个部分
for(Re j=1;j<=m;++j)//处理每一列
for(Re i=1;i<=n;++i)
if(A[i][j]<2)//不是墙,需要建点
if(A[i-1][j]>1)idz[i][j]=++n2;//前面是墙,新开一部分
else idz[i][j]=idz[i-1][j];//前面不是墙,与其算作一个部分
for(Re i=1;i<=n;++i)
for(Re j=1;j<=m;++j)
if(!A[i][j])add(idh[i][j],idz[i][j]);//没有陷阱就连边
for(Re i=1;i<=n1;++i){//跑二分图最大匹配
for(Re j=1;j<=n2;++j)pan[j]=0;
ans+=dfs(i);
}
printf("%d\n",ans);
for(Re i=1;i<=n;++i)//输出答案利用子匈牙利算法的特性
for(Re j=1;j<=m;++j)//match数组记录了所有的匹配边
if(!A[i][j]&&idh[i][j]==match[idz[i][j]])printf("%d %d\n",i,j);
// fclose(stdin);
// fclose(stdout);
return 0;
}
【题解】宫廷守卫 [P1263]的更多相关文章
- 洛谷P1263 宫廷守卫
P1263 宫廷守卫 题目描述 从前有一个王国,这个王国的城堡是一个矩形,被分为M×N个方格.一些方格是墙,而另一些是空地.这个王国的国王在城堡里设了一些陷阱,每个陷阱占据一块空地. 一天,国王决定在 ...
- 洛谷 P1263 宫廷守卫
被这道题折腾了 \(2\) 个小时. 按照题意,每个守卫的上下左右四个方向上应当都是墙,而不能出现其他的守卫. 如图是一个合法的放置方案.每个守卫四个方向上都是墙(包括宫廷外墙). 如图是一个非法的放 ...
- 洛谷P1263 || 巴蜀2311 宫廷守卫
题目描述 从前有一个王国,这个王国的城堡是一个矩形,被分为M×N个方格.一些方格是墙,而另一些是空地.这个王国的国王在城堡里设了一些陷阱,每个陷阱占据一块空地. 一天,国王决定在城堡里布置守卫,他希望 ...
- 【Codevs3567】宫廷守卫
Position: http://codevs.cn/problem/3567/ Description 从前有一个王国,这个王国的城堡是一个矩形,被分为M×N个方格.一些方格是墙,而另一些是空地.这 ...
- 二分图&网络流初步
链接 : 最小割&网络流应用 EK太低级了,不用. 那么请看:#6068. 「2017 山东一轮集训 Day4」棋盘,不用EK你试试? dinic模板及部分变形应用见zzz大佬的博客:网络流学 ...
- 【题解】BZOJ4883: [Lydsy1705月赛]棋盘上的守卫(最小生成基环森林)
[题解]BZOJ4883: [Lydsy1705月赛]棋盘上的守卫(最小生成基环森林) 神题 我的想法是,每行每列都要有匹配且一个点只能匹配一个,于是就把格点和每行每列建点出来做一个最小生成树,但是不 ...
- TYVJ-P1864 守卫者的挑战 题解
P1864 [Poetize I]守卫者的挑战 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 打开了黑魔法师Vani的大门,队员们在迷宫般的路上漫无目的地搜 ...
- BZOJ5324 & 洛谷4563 & LOJ2545:[JXOI2018]守卫——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=5324 https://www.luogu.org/problemnew/show/P4563 ht ...
- 【TYVJ1864】[Poetize I]守卫者的挑战 概率与期望
[TYVJ1864][Poetize I]守卫者的挑战 描述 打开了黑魔法师Vani的大门,队员们在迷宫般的路上漫无目的地搜寻着关押applepi的监狱的所在地.突然,眼前一道亮光闪过."我 ...
随机推荐
- a标使用window.open()方法
<a href="javascript:window.open('../Left_B/L_Gong_gao_Index', 'TencentLogin', 'width=1920px, ...
- vuex防止数据刷新数据刷掉
replaceState replaceState(state: Object) 替换store的根状态,仅用状态合并或者时光旅行调试 // 在页面加载时读取localStorage里的状态信息 if ...
- 入职一个月后 对.net的感想
我本来应该找Java工程师的岗位的,因种种原因进入了.net开发工程师.然后,我进入了一扇新世界的大门. 1.语法不同,思想相同. 刚入职那几天,每天都好蒙,.net代码语法啥的都和Java不一样,a ...
- 更换Ubuntu软件源
对于Ubuntu系统, 不同的版本的源都不一样,每一个版本都有自己专属的源. 而对于 Ubuntu 的同一个发行版本,它的源又分布在全球范围内的服务器上.Ubuntu 默认使用的官方源的服务器在欧洲, ...
- 虚拟机安装苹果macOS系统
Windows10系统虚拟机vmware15上装macos系统 一.简要步骤: 1.准备软件. 2.关闭VMware服务: 3.解压unlocker,运行文件: 4.启动vmware,选择macOS镜 ...
- c# 第15节 StringBuilder
本节内容: 1:StringBuilder 2:内容总结 1:StringBuilder 实例: 2:内容总结 项目:
- RST复位报文
复位报文段: 一些特殊情况,TCP一端向另一端发送复位报文,以通知对方关闭链接或者重新建立链接. 产生复位报文的三种情况: 1. 当客户端访问一个不存在的端口时,目标主机会给客户端发送一个复位报文段. ...
- 5 Ways AI is Transforming the Finance Industry
https://marutitech.com/ways-ai-transforming-finance/ As global technology has evolved over the years ...
- JDOJ 1152 是否是素数
1152: 是否是素数 https://neooj.com:8082/oldoj/problem.php?id=1152 题目描述 写一个判断素数的函数,在主函数输入一个整数,输出是否是素数的消息. ...
- BZOJ练习记
决定从头到尾干一波BZOJ!可能会写没几题就停下吧,但还是想学学新姿势啦. 1001. [BeiJing2006]狼抓兔子 即求 $(1, 1)$ 到 $(n, m)$ 的最小割.跑 dinic 即可 ...