考虑将最上中最左的跳蚤孤立,容易发现他的上面和左面没有跳蚤,因此只需要将他的右边和下边替换掉就可以了
答案为-1有两种情况:1.c>=n*m-1;2.c=n*m-2且这两只跳蚤相邻
对于其他情况,将所有跳蚤建图后判断:1.是否有多个连通块;2.是否有割点即可,由于跳蚤数量很多,容易发现只需要选择周围5*5的范围内有蛐蛐的跳蚤建图即可
只选择3*3会有反例(以下q表示蛐蛐,t表示跳蚤):
ttttt
tttqt
ttttt
tqttt
ttttt
(注意如果c=0那么答案为((n>1)&&(m>1))+1)

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 100005
4 #define mp make_pair
5 #define pii pair<int,int>
6 struct ji{
7 int nex,to;
8 }edge[N<<5];
9 queue<pii >q;
10 map<pii ,int>a,mat;
11 int t,n,m,k,x[N],y[N],tx[4]={-1,0,0,1},ty[4]={0,-1,1,0};
12 int V,E,head[N<<2],vis[N<<2],dfn[N<<2],low[N<<2],sum[N<<2];
13 void add(int x,int y){
14 edge[E].nex=head[x];
15 edge[E].to=y;
16 head[x]=E++;
17 }
18 void dfs(int k,int fa){
19 low[k]=dfn[k]=++dfn[0];
20 for(int i=head[k];i!=-1;i=edge[i].nex)
21 if (edge[i].to!=fa)
22 if (dfn[edge[i].to])low[k]=min(low[k],dfn[edge[i].to]);
23 else{
24 dfs(edge[i].to,k);
25 low[k]=min(low[k],low[edge[i].to]);
26 if (dfn[k]<=low[edge[i].to])sum[k]++;
27 }
28 }
29 int bfs(int x,int y){
30 a.clear();
31 mat[mp(x,y)]=2;
32 q.push(mp(x,y));
33 for(int i=1;i<=V;i++)vis[i]=dfn[i]=sum[i]=0;
34 V=E=dfn[0]=0;
35 while (!q.empty()){
36 x=q.front().first;
37 y=q.front().second;
38 q.pop();
39 for(int dx=-2;dx<3;dx++)
40 for(int dy=-2;dy<3;dy++){
41 if ((x+dx<1)||(y+dy<1)||(x+dx>n)||(y+dy>m))continue;
42 pii o=mp(x+dx,y+dy);
43 if (mat[o]==1){
44 mat[o]=2;
45 q.push(o);
46 }
47 if (mat[o]==2)continue;
48 if (!a[o]){
49 a[o]=++V;
50 head[V]=-1;
51 for(int dz=0;dz<4;dz++){
52 int p=a[mp(x+dx+tx[dz],y+dy+ty[dz])];
53 if (p){
54 add(V,p);
55 add(p,V);
56 }
57 }
58 }
59 if (a[o]>0)vis[a[o]]|=((-2<dx)&&(dx<2)&&(-2<dy)&&(dy<2));
60 }
61 }
62 dfs(1,0);
63 if (dfn[0]<V)return 0;
64 if ((vis[1])&&(sum[1]>1))return 1;
65 for(int i=2;i<=V;i++)
66 if ((vis[i])&&(sum[i]))return 1;
67 return 2;
68 }
69 int main(){
70 scanf("%d",&t);
71 memset(head,-1,sizeof(head));
72 while (t--){
73 scanf("%d%d%d",&n,&m,&k);
74 if (k>=1LL*n*m-1){
75 for(int i=1;i<=k;i++)scanf("%*d%*d");
76 printf("-1\n");
77 continue;
78 }
79 mat.clear();
80 for(int i=1;i<=k;i++){
81 scanf("%d%d",&x[i],&y[i]);
82 mat[mp(x[i],y[i])]=1;
83 }
84 int ans=2;
85 for(int i=1;i<=k;i++)
86 if (mat[mp(x[i],y[i])]==1)ans=min(ans,bfs(x[i],y[i]));
87 if (((n==1)||(m==1))&&(ans))ans=1;
88 if ((1LL*n*m-2==k)&&(ans))ans=-1;
89 printf("%d\n",ans);
90 }
91 }

[bzoj4651]网格的更多相关文章

  1. 【BZOJ4651】【NOI2016】网格(Tarjan,哈希)

    [BZOJ4651][NOI2016]网格(Tarjan,哈希) 题面 BZOJ 洛谷 题解 首先把题目稍微变得好说一些,给定一个网格,已经删去了若干个格子 问最少删去多少个格子使得图不连通. 这题的 ...

  2. [UOJ#220][BZOJ4651][Noi2016]网格

    [UOJ#220][BZOJ4651][Noi2016]网格 试题描述 跳蚤国王和蛐蛐国王在玩一个游戏. 他们在一个 n 行 m 列的网格上排兵布阵.其中的 c 个格子中 (0≤c≤nm),每个格子有 ...

  3. [BZOJ4651][NOI2016]网格(Tarjan)

    下面直接给出结论,相关证明见官方题解. 1.若跳蚤数不超过1或仅有两只跳蚤且相邻,则答案为-1. 2.若跳蚤形成的连通块个数大于1,则答案为0. 3.若跳蚤之间建图存在割点,则答案为1. 4.否则为2 ...

  4. BZOJ4651 & 洛谷1173 & UOJ220:[NOI2016]网格——题解(附debug数据)

    https://www.lydsy.com/JudgeOnline/problem.php?id=4651 https://www.luogu.org/problemnew/show/P1173#su ...

  5. BZOJ4651 NOI2016网格(割点)

    首先显然可以通过孤立角落里的跳蚤使其不连通,所以只要有解答案就不会大于2.同样显然的一点是当且仅当跳蚤数量<=2且连通时无解.做法其实也很显然了:特判无解,若跳蚤不连通输出0,否则看图中是否无割 ...

  6. BZOJ4651/UOJ220 [Noi2016]网格

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  7. 并不对劲的bzoj4651:loj2084:uoj220:p1173:[NOI2016]网格

    题目大意 有一个\(n*m\)(\(n,m\leq10^9\))的网格,每个格子是空地或障碍(\(障碍数\leq10^5\)) 定义两块空地连通,当且仅当它们是"相邻的两块空地"或 ...

  8. C#中如何创建PDF网格并插入图片

    这篇文章我将向大家演示如何以编程的方式在PDF文档中创建一个网格,并将图片插入特定的网格中. 网上有一些类似的解决方法,在这里我选择了一个免费版的PDF组件.安装控件后,创建新项目,添加安装目录下的d ...

  9. pcl曲面网格模型的三种显示方式

    pcl网格模型有三种可选的显示模式,分别是面片模式(surface)显示,线框图模式(wireframe)显示,点模式(point)显示.默认为面片模式进行显示.设置函数分别为: void pcl:: ...

随机推荐

  1. Servlet和Servlet容器

    Java Servlet(Java服务器小程序)是一个基于Java技术的Web组件,运行在服务器端,它由Servlet容器所管理,用于生成动态的内容, Servlet是平台独立的Java类,编写一个S ...

  2. python中的 * 和 ** 作用含义

    python中的 * 和 ** ,能够让函数支持任意数量的参数,它们在函数定义和调用中,有着不同的目的 一. 打包参数 * 的作用:在函数定义中,收集所有位置参数到一个新的元组,并将整个元组赋值给变量 ...

  3. GAN实战笔记——第二章自编码器生成模型入门

    自编码器生成模型入门 之所以讲解本章内容,原因有三. 生成模型对大多数人来说是一个全新的领域.大多数人一开始接触到的往往都是机器学习中的分类任务--也许因为它们更为直观:而生成模型试图生成看起来很逼真 ...

  4. c语言中一条竖线是什么符号?

    "|"在C语言中表示按位或,是双目运算符.其功能是参与运算的两数各对应的二进位(也就是最后一位)相或.只要对应的二个二进位有一个为1时,结果位就为1.参与运算的两个数均以补码出现. ...

  5. SpringMVC、Spring、MyBatis整合(IDEA版)

    1 环境准备 1.1 软件架构 JDK 1.8 Spring 4.x Mybatis 3.x Maven 3.x MySQL 5.7 1.2 创建数据库 创建数据库,数据库名ssm-demo,字符集u ...

  6. 【c++ Prime 学习笔记】第14章 重载运算与类型转换

    14.1 基本概念 重载的运算符是特殊的函数:名字由关键字operator后接要定义的算符共同组成,也有返回类型.参数列表.函数体. 重载运算符函数的参数量与该算符作用的运算对象数量一样多 除重载调用 ...

  7. 短短 29 天,应对高峰 100W+ 访问,看浙大如何交出满分答卷

    疫情期间"停课不停教,停课不停学",线上开课第一天,浙江大学网上开课平台访问量即突破100 万次,访客数3万余人,最高峰达 1.1万人同时在线,发起课程直播2000余场,然而系统却 ...

  8. UltraSoft - DDL Killer - Alpha 项目展示

    团队介绍 CookieLau fmh 王 FUJI LZH DZ Monster PM & 后端 前端 前端 前端 后端 后端 软件介绍 项目简介 项目名称:DDLKiller 项目描述:&q ...

  9. Canal Server发送binlog消息到Kafka消息队列中

    Canal Server发送binlog消息到Kafka消息队列中 一.背景 二.需要修改的地方 1.canal.properties 配置文件修改 1.修改canal.serverMode的值 2. ...

  10. C语言中都有哪些常见的数据结构你都知道几个??

    上次在面试时被面试官问到学了哪些数据结构,那时简单答了栈.队列/(ㄒoㄒ)/~~其它就都想不起来了,今天有空整理了一下几种常见的数据结构,原来我们学过的数据结构有这么多~ 首先,先来回顾下C语言中常见 ...