【题解】宫廷守卫 [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的监狱的所在地.突然,眼前一道亮光闪过."我 ...
随机推荐
- RT-Thread点亮led
下载默认工程 https://www.rt-thread.org/ 配置rtconfig.h #define STM32F103RE //修改成自己的板子 #define RT_HSE_VALUE 8 ...
- Violet音乐社区 - 总结报告
目录 一.项目概述 1.1 项目背景 1.2 编写目的 1.3 项目文档 1.4 项目源码 1.5 项目成果 二.个人工作总结 1.1 工作概览 1.1.1 作为项目组组长 1.1.2 作为项目组成员 ...
- osi7层
- [linux] 多进程和多线程
1.在Linux系统下,启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维护它的代码段.堆栈段和数据段,这是一种”昂贵”的多任务工作方式.2.而运行于一个进程中的多个线程,它们彼此之间使 ...
- Linux安装php-mysql提示需要:libmysqlclient.so.18()(64bit)的解决办法
Linux安装php-mysql提示需要:libmysqlclient.so.18()(64bit)的解决办法 在LNMP编译环境下安装zabbix会出现 执行:yum -y install net- ...
- Flask请求和应用上下文源码分析
flask的request和session设置方式比较新颖,如果没有这种方式,那么就只能通过参数的传递. flask是如何做的呢? 1:本地线程,保证即使是多个线程,自己的值也是互相隔离 1 im ...
- C语言之++和--
#include<stdio.h> int main(void) { int a; a = ; printf("a++ = %d\n", a++); printf(&q ...
- 201871010104-陈园园 《面向对象程序设计(java)》第十三周学习总结
201871010104-陈园园 <面向对象程序设计(java)>第十三周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ ...
- 面向对象程序设计(Java) 第6-7周学习指导及要求
面向对象程序设计(Java)第6-7周学习指导及要求 (2019.9.29-2019.10.8) 学习目标 深入理解程序设计中算法与程序的关系: 深入理解java程序设计中类与对象的关系: 理解O ...
- opencv归一化图像
cv::normalize(src, dst, 0.0, 255.0, cv::NORM_MINMAX);