下面直接给出结论,相关证明见官方题解。

1.若跳蚤数不超过1或仅有两只跳蚤且相邻,则答案为-1。

2.若跳蚤形成的连通块个数大于1,则答案为0。

3.若跳蚤之间建图存在割点,则答案为1。

4.否则为2。

这样就有70分了。但是图太大了,显然有很多没用的跳蚤被统计进答案。

考虑到造成不连通的情况一定在蛐蛐附近,于是将每个蛐蛐周围5*5的格子中的24个跳蚤全部取出,内圈8个称为一级空地,外圈称为二级空地。之考虑这些点即可,复杂度就只与蛐蛐个数相关了。

将所有被取出的跳蚤建图,求连通块个数和割点即可。

几个注意点:

1.特判n=1或m=1的情况。

2.只有一级空地与在网格边缘的二级空地成为割点答案才能是0。

3.关于常数问题:不要用memset,判断元素是否存在用S.find(x)!=S.end()不要用S.count(x)。

4.下面代码在UOJ被叉掉了,以及O2会产生各种无解的错误,比如bool tag[N]如果写在int那行的上面就会被系统杀死。

 #include<map>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define mem(a) memset(a,0,sizeof(a))
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
#define For(i,x) for (int i=h[x],k; i; i=nxt[i])
using namespace std; const int N=;
const int dx[]={,,,,-},dy[]={,,,-,};
int T,n,m,c,cnt,tim,nd,id[][],dfn[N],low[N],fa[N],h[N],nxt[N<<],to[N<<];
bool tag[N];
struct P{ int x,y; }p[N],s[];
map<P,int>S;
bool operator <(const P &a,const P &b){ return (a.x==b.x) ? a.y<b.y : a.x<b.x; }
void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; }
int get(int x){ return (fa[x]==x) ? x : fa[x]=get(fa[x]); }
bool chk(int x,int y){ return x>= && x<=n && y>= && y<=m; } inline int rd(){
int x=; char ch=getchar();
while (ch<'' || ch>'') ch=getchar();
while (ch>='' && ch<='') x=(x<<)+(x<<)+(ch^),ch=getchar();
return x;
} bool tarjan(int x,int fa){
dfn[x]=low[x]=++tim; int son=;
For(i,x) if ((k=to[i])!=fa){
if (dfn[k]) low[x]=min(low[x],dfn[k]);
else{
if (tarjan(k,x)) return ;
son++; low[x]=min(low[x],low[k]);
if (((fa && low[k]>=dfn[x]) || (!fa && son>)) && tag[x]) return ;
}
}
return ;
} int main(){
freopen("grid.in","r",stdin);
freopen("grid.out","w",stdout);
for (scanf("%d",&T); T--; ){
scanf("%d%d%d",&n,&m,&c); cnt=; nd=; tim=; S.clear();
rep(i,,c) p[i].x=rd(),p[i].y=rd(),S[p[i]]=-;
if (1ll*n*m-c<=){ puts("-1"); continue; }
if (1ll*n*m-c==){
int tot=;
rep(i,,n) rep(j,,m) if (S.find((P){i,j})==S.end()) s[++tot]=(P){i,j};
if (abs(s[].x-s[].x)+abs(s[].y-s[].y)==) puts("-1"); else puts("");
continue;
}
rep(i,,c){
rep(x,-,) rep(y,-,) if (chk(p[i].x+x,p[i].y+y)){
int x1=p[i].x+x,y1=p[i].y+y;
if (S.find((P){x1,y1})==S.end())
id[x+][y+]=++nd,S[(P){x1,y1}]=nd,tag[nd]=,h[nd]=,dfn[nd]=,fa[nd]=nd;
else id[x+][y+]=S[(P){x1,y1}];
if (x1== || x1==n || y1== || y1==m || (abs(x)<= && abs(y)<=)) tag[id[x+][y+]]=;
}else S[(P){p[i].x+x,p[i].y+y}]=-,id[x+][y+]=-;
rep(x,,) rep(y,,) rep(k,,){
int x1=x+dx[k],y1=y+dy[k];
if (x1< || x1> || y1< || y1> || id[x][y]==- || id[x1][y1]==-) continue;
add(id[x][y],id[x1][y1]);
fa[get(id[x1][y1])]=get(id[x][y]);
}
}
bool flag=;
rep(i,,c){
int t=-;
rep(x,-,) rep(y,-,){
int w=S[(P){p[i].x+x,p[i].y+y}];
if (w==-) continue;
if (t==-) t=get(w); else { if (t!=get(w)){ flag=; break; } }
}
if (flag) break;
}
if (flag){ puts(""); continue; }
if (n== || m==){ puts(""); continue; }
rep(i,,nd) if (!dfn[i] && tarjan(i,)) { puts(""); flag=; break; }
if (!flag) puts("");
}
return ;
}

[BZOJ4651][NOI2016]网格(Tarjan)的更多相关文章

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

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

  2. BZOJ4651 NOI2016网格(割点)

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

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

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

  4. BZOJ4651/UOJ220 [Noi2016]网格

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

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

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

  6. UOJ#220. 【NOI2016】网格 Tarjan

    原文链接www.cnblogs.com/zhouzhendong/p/UOJ220.html 前言 真是一道翔题. 草率题解 -1 的情况很好判,只有两种情况: n * m - c < 2 或者 ...

  7. [Noi2016]网格

    来自FallDream的博客,未经允许,请勿转载,谢谢.   跳蚤国王和蛐蛐国王在玩一个游戏. 他们在一个 n 行 m 列的网格上排兵布阵.其中的 c 个格子中 (0≤c≤nm),每个格子有一只蛐蛐, ...

  8. 洛谷P1173 [NOI2016]网格

    这个码量绝对是业界大毒瘤...... 300行,6.5k,烦的要死...... 题意:给你一个网格图,里面有0或1.你需要把一些0换成1使得存在某两个0不四联通.输出最小的换的数量.无解-1. n,m ...

  9. UOJ220 [NOI2016] 网格 【割顶】【并查集】

    题目分析: 答案显然只有{-1,0,1,2}四种. 对于答案等于-1的情况,只有两种情况,一种是只剩一只跳蚤,另一种是只剩两只跳蚤且他们四连通,这个很好判. 对于答案等于0的情况,那说明联通块大于1, ...

随机推荐

  1. NYOJ 756 重建二叉树 (二叉树)

    题目链接 描述 题目很简单,给你一棵二叉树的后序和中序序列,求出它的前序序列(So easy!). 输入 输入有多组数据(少于100组),以文件结尾结束.每组数据仅一行,包括两个字符串,中间用空格隔开 ...

  2. Entity Framework(EF的Database First方法)

    EntityFramework,是Microsoft的一款ORM(Object-Relation-Mapping)框架.同其它ORM(如,NHibernate,Hibernate)一样, 一是为了使开 ...

  3. 使用JSON语法创建JS对象(重要)

    JS对象的键值可以加单引号或者不加或者加双引号 JSON语法提供了一种更简单的方式来创建对象,可以避免书写函数,也可避免用new关键字,可以直接创建一个JS对象,使用一个花括号,然后将每个属性写成&q ...

  4. (5)剑指Offer之栈变队列和栈的压入、弹出序列

    一 用两个栈实现队列 题目描述: 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 问题分析: 先来回顾一下栈和队列的基本特点: 栈:后进先出(LIFO) 队列: ...

  5. Android中的通信Volley

    1. Volley简介 我们平时在开发Android应用的时候不可避免地都需要用到网络技术,而多数情况下应用程序都会使用HTTP协议来发送和接收网络数据.Android系统中主要提供了两种方式来进行H ...

  6. koa中间层 文件下载的请求转发

    背景: 前端用a标签发起下载文档的get请求 node中间层接到get请求后将请求转发到java后端 java后端返回文档流传递给node中间层 好处: 后端的java业务逻辑层接口.数据库不向外部暴 ...

  7. css预处理scss环境配置

    css 预处理器 CSS 预处理器用一种专门的编程语言,进行 Web css编码,然后再编译成正常的 CSS 文件,以供项目使用:说简单点就是在某个环境下写css 可以写变量.表达式.嵌套等,在通过该 ...

  8. Percona XtraDB Cluster(PXC) -集群环境安装

    Percona XtraDB Cluster(PXC)   ---服务安装篇   1.测试环境搭建: Ip 角色 OS PXC-version 172.16.40.201 Node1 Redhat/C ...

  9. HTML 禁止显示input默认提示信息

    看问题 html代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...

  10. MongoDB权威指南--笔记

    mongodb并不具备一些在关系型数据库中很普遍的功能,如连接和复杂的多行事务. 集合-->文档-->id id在文档所属的集合中是唯一的. db.help()查看数据库级别的帮助,db. ...