解析

看起来很不码农但写起来其实还行的一道题。
主要也是因为我贺题解把所有的雷都避过去了

首先一个比较显然的结论是:通过堵角上的,答案不超过2。
所以本题只要把答案是-1,0,1,2的情况判出来即可。

-1是只有一个空位或只有两个相邻空位。
0是原图不连通。
1是原图存在割点。
其他都是2。

做完了?太天真了。

n,m≤109n,m\le 10^9n,m≤109

那咋办?
注意到,c≤105c\le 10^5c≤105,这张图非常稀疏,在空网格上暴力tarjan看起来非常的蠢。
那怎么办?
我们尝试对于每个蛐蛐,提取出它周围的格子,这样的节点数就变成了 O(c)O(c)O(c) 级别。(感觉有些像华容道那个题)
然后在新的图上tarjan就好了。

还要注意亿点点坑点:

  1. 提出的“周围一圈”应该是 5×55\times 55×5 而不是 3×33\times 33×3,同时只有距离最近蛐蛐曼哈顿距离为1的点是割点才算割点。
  2. 判联通的时候要把8联通的蛐蛐全找出来一起判。

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define ok debug("OK\n")
using namespace std;const int N=1e5+100;const int mod=1333331;
const double inf=1e9;
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)) {if(c=='-')f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}int n,m,c;
bool flag=0;struct node{int to,nxt;
}p[N*25*4*2];
int fi[N*25],cnt;
inline void addline(int x,int y){p[++cnt]=(node){y,fi[x]};fi[x]=cnt;
}struct Hash{node p[N*25];int fi[mod+1],tot,cnt;ll key[N*25];int id[N*25];void ins(int x,int y,int Id){ll w=1ll*x*(m+1)+y,o=w%mod;++tot;id[tot]=Id;key[tot]=w;    p[++cnt]=(node){tot,fi[o]};fi[o]=cnt;//debug("add o=%lld fi=%d\n",o,fi[o]);}int find(int x,int y){ll w=1ll*x*(m+1)+y,o=w%mod;for(int i=fi[o];~i;i=p[i].nxt){//debug("o=%lld i=%d\n",o,i);//ok;if(key[p[i].to]==w) return id[p[i].to];}return 0;}void init(){tot=0;memset(fi,-1,sizeof(fi));cnt=-1;}
}mp;int tot;int x[N],y[N];
bool jd[N*25];
int d24x[25]={0,-2,-2,-2,-2,-2,-1,-1,-1,-1,-1,0,0,0,0,1,1,1,1,1,2,2,2,2,2},d24y[25]={0,-2,-1,0,1,2,-2,-1,0,1,2,-2,-1,1,2,-2,-1,0,1,2,-2,-1,0,1,2};
int d8x[9]={0,-1,-1,-1,0,0,1,1,1},d8y[9]={0,-1,0,1,-1,1,-1,0,1};
int d4x[5]={0,-1,0,0,1},d4y[5]={0,0,-1,1,0};int cut;
int dfn[N*25],low[N*25],tim,bel[N*25],Id;
void tarjan(int x,int rt=0){dfn[x]=low[x]=++tim;bel[x]=Id;int son(0);for(int i=fi[x];~i;i=p[i].nxt){int to=p[i].to;//if(to<=c) continue;if(!dfn[to]){tarjan(to);son++;if(low[to]>=dfn[x]){cut+=jd[x];}low[x]=min(low[x],low[to]);}else low[x]=min(low[x],dfn[to]);}if(rt&&son==1) cut-=jd[x];return;
}bool vis[N];
int nowId;
void dfs(int x,int y){int now=mp.find(x,y);vis[now]=1;for(int d=1;d<=8;d++){int nx=x+d8x[d],ny=y+d8y[d];if(nx<1||nx>n||ny<1||ny>m) continue;int to=mp.find(nx,ny);if(to>c){if(nowId==0) nowId=bel[to];else if(nowId!=bel[to]) nowId=-1;}else if(!vis[to]) dfs(nx,ny);    }
}void clear(){mp.init();memset(fi,-1,sizeof(int)*(tot+1));cnt=-1;memset(jd,0,sizeof(int)*(tot+1));cut=tim=Id=0;memset(dfn,0,sizeof(int)*(tot+1));memset(low,0,sizeof(int)*(tot+1));memset(bel,0,sizeof(int)*(tot+1));memset(vis,0,sizeof(int)*(c+1));tot=0;
}void work(){n=read();m=read();tot=c=read();for(int i=1;i<=c;i++){x[i]=read();y[i]=read();mp.ins(x[i],y[i],i);    }for(int i=1;i<=c;i++){for(int d=1;d<=24;d++){int nx=x[i]+d24x[d],ny=y[i]+d24y[d];if(nx<1||nx>n||ny<1||ny>m) continue;      if(!mp.find(nx,ny)){mp.ins(nx,ny,++tot);int x=tot;for(int d=1;d<=4;d++){int nnx=nx+d4x[d],nny=ny+d4y[d];int to=mp.find(nnx,nny);if(to&&to>c){//printf("d=%d (%d %d) -> (%d %d)\n",d,nx,ny,nnx,nny);addline(x,to);addline(to,x);}}}int to=mp.find(nx,ny);if(to<=c) continue;if(abs(nx-x[i])<=1&&abs(ny-y[i])<=1) jd[to]=1;}}if(flag) for(int i=1;i<=n;i++){for(int j=1;j<=m;j++) printf("%d ",mp.find(i,j));puts("");}for(int i=c+1;i<=tot;i++){if(!dfn[i]){++Id;tarjan(i,1);}}if(1ll*n*m-c<2||(1ll*n*m-c==2&&(Id==1||n*m==2))){puts("-1");return;}for(int i=1;i<=c;i++){if(!vis[i]){nowId=0;dfs(x[i],y[i]);if(nowId==-1){puts("0");return;}}}if(cut||n==1||m==1) puts("1");else puts("2");return;
}signed main(){#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);#endifmemset(fi,-1,sizeof(fi));cnt=-1;int T=read();while(T--){clear();work();}return 0;
}

洛谷P1173:[NOI2016] 网格(tarjan、离散化)相关推荐

  1. 洛谷P1173 网格

    题目描述 跳蚤国王和蛐蛐国王在玩一个游戏. 他们在一个 nn 行 mm 列的网格上排兵布阵.其中的 cc 个格子中 (0 \leq c \leq n\cdot m)(0≤c≤n⋅m),每个格子有一只蛐 ...

  2. 洛谷 - P4168 [Violet]蒲公英(分块+离散化)

    题目链接:点击查看 题目大意:给出一个长度为 n 的数列,再给出 m 次查询,每次查询区间 [ l , r ] 内的众数,要求强制在线 题目分析:对于这个题意来说,如果允许离线的话,完全可以用莫队当模 ...

  3. 洛谷1262 间谍网络 tarjan缩点

    题目描述 由于外国间谍的大量渗入,国家安全正处于高度的危机之中.如果A间谍手中掌握着关于B间谍的犯罪证据,则称A可以揭发B.有些间谍收受贿赂,只要给他们一定数量的美元,他们就愿意交出手中掌握的全部情报 ...

  4. 洛谷 2921 记忆化搜索 tarjan 基环外向树

    洛谷 2921 记忆化搜索 tarjan 传送门 (https://www.luogu.org/problem/show?pid=2921) 做这题的经历有点玄学,,起因是某个random题的同学突然 ...

  5. 洛谷 P3388 【模板】割点(割顶) 根+非根+dfn[]+low[]+不一样的Tarjan算法

    洛谷  P3388 [模板]割点(割顶)  根+非根+dfn[]+low[]+不一样的Tarjan算法 Tarjan算法,详见https://blog.csdn.net/mrcrack/article ...

  6. (Tarjan)洛谷P3387【模板】缩点

    洛谷P3387[模板]缩点 思路: 虽然是缩点模板题,但是明显感觉比同一个题单中的其他题都难. 题目思路已经提供给你:Tarjan缩点+DAGdp.就是用Tarjan缩点,重新建图之后,边拓扑排序边建 ...

  7. SSL 2344 洛谷 2835 信息学奥赛一本通 1383 刻录光盘#floyd,tarjan,kosaraju#

    洛谷请关掉优化 题目 求有多少个连通块 分析 floyd+并查集 floyd代码 #include <cstdio> #include <cctype> #include &l ...

  8. 洛谷·[POI2005]SKA-Piggy Banks 小猪存钱罐【Tarjan 并查集

    初见安~这里是传送门:洛谷P3420 题目描述3 Byteazar the Dragon has NN piggy banks. Each piggy bank can either be opene ...

  9. 【tarjan强连通分量】洛谷P1726 上白泽慧音

    [tarjan强连通分量]洛谷P1726 上白泽慧音 题目传送门 妥妥的强连通模板啊(详细解释戳这里) #include <bits/stdc++.h> #define MAXN 5005 ...

最新文章

  1. DOS、Mac 和 Unix 文件格式+ UltraEdit使用
  2. 实用ExtJS教程100例-009:ExtJS Form无刷新文件上传
  3. SQL-92标准 中文翻译——定义、记号和约定 (定义)
  4. Cocos2d-x中使用第三方so库
  5. Android测试入门学习
  6. cacti实现微信告警功能
  7. Quartz.NET实现作业调度
  8. hdu3397 线段树 成段更新
  9. python时间戳转为datetime格式_python 时间 时间戳 转换
  10. jquery学习系列1(Ready)
  11. win7无法识别linux usb设备,win7无法安装usb驱动解决工具
  12. 如何巧用Microsoft edge浏览器合并pdf文件
  13. 如何制作BAT(Windows批处理文件)病毒
  14. PCA:详细解释主成分分析
  15. eventFilter能进入dragEnter但没有event::drog
  16. Qt对象间的父子关系
  17. 香港黄金配角吴孟达去世,80后程序员以轮播图来悼念达叔,达叔一路走好!
  18. nginx的安装和配置
  19. python把一个文件夹内子文件夹下所有文件复制到指定目录下
  20. zabbix-邮箱报警与微信报警

热门文章

  1. 数据可视化,带给你的惊艳并不止这一点!
  2. 编程到底难在哪里? 从一个美国实习生的故事说起
  3. 代码传奇 | 明明可以靠颜值 却用代码把人类送上了月球的女人——Margaret Hamilton
  4. 2014全国计算机二级ms office,2014计算机二级MS Office真题及答案
  5. 件工程项目开发最全文档模板_一文带你了解微信小程序社区和小程序开发
  6. java 子类 复制_关于java子类继承来的属性与方法究竟是完全复制还是共用使用...
  7. Java交流|面试最后一问:你有什么问题想问我吗?
  8. pythonjam进不去怎么办_教程看了一遍又一遍,自学Python还是连门都进不去?
  9. java access dbq_Java-Access汇总
  10. ubuntu安装mysql_Ubuntu18.04下安装MySQL