[Noi2016]网格
来自FallDream的博客,未经允许,请勿转载,谢谢。
跳蚤国王和蛐蛐国王在玩一个游戏。
T<=20 1≤n,m≤10^9,0≤c≤min(nm,10^5) ∑c<=10^5
2s/1G
真是很蛋疼
当跳蚤数量小于2或者正好是一对还粘一起的时候答案是-1
当跳蚤本身不联通的时候答案是0
当存在一个点把图割开的时候是1
不然就是2
好像很简单 乱写了一通之后 成功获得了16分 真轻松 然后就去看了看题解
只保留在蛐蛐周围的5*5的格子内的跳蚤,四联通建图 建出的图等价 割点可以tarjan求出
然后如果有跳蚤不联通 那么会有一个蛐蛐的八联通块周围有两个不同的跳蚤联通块
感觉自己的码力不是很行啊 乱写一通 就这么丑了(吐血)
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#define ll long long
#define MN 100000
#define mod 2333333
using namespace std;
inline int read()
{
int x = ; char ch = getchar();
while(ch < '' || ch > '') ch = getchar();
while(ch >= '' && ch <= ''){x = x * + ch - '';ch = getchar();}
return x;
}
int n,m,c,top,dn,ans,bel[MN*+],Cnt=,Col=,head[MN*+],en,tot,dfn[MN*+],low[MN*+],col[MN*+];
vector<int> v[MN+],V[MN+];
bool Cut[MN*+],b[MN+];
struct P
{
int x,y;
P(int x=,int y=):x(x),y(y){}
P operator+(P b){return P(x+b.x,y+b.y);}
}p[MN+],Q[],q[MN*+];
struct edge{int to,next;}e[MN*+];
struct My_Map
{
int Head[mod+],cnt;
struct Hash{ll ha;int x,next;}s[*MN+];
void clear()
{
cnt=;
memset(Head,,sizeof(Head));
}
void ins(int X,int Y)
{
ll Ha=1LL*X*m+Y;int j=Ha%mod;
s[++cnt]=(Hash){Ha,++Cnt,Head[j]};
Head[j]=cnt;
}
int Check(int X,int Y)
{
ll Ha=1LL*X*m+Y;int j=Ha%mod;
for(int i=Head[j];i;i=s[i].next)
if(s[i].ha==Ha) return s[i].x;
return ;
}
}mp;
inline void ins(int f,int t){e[++en]=(edge){t,head[f]};head[f]=en;}
inline int abs(int x){return x<?-x:x;}
bool Check()
{
if(1LL*n*m-c>) return false;
if(1LL*n*m-c<=) return true;
top=;
for(int i=;i<=n;++i)
for(int j=;j<=m&&top<;++j)
if(!mp.Check(i,j)) Q[++top]=P(i,j);
if(Q[].x==Q[].x&&abs(Q[].y-Q[].y)==) return true;
if(Q[].y==Q[].y&&abs(Q[].x-Q[].x)==) return true;
return false;
}
const int dis[][]={{,},{-,},{,},{,-}};
void build()
{
for(int i=;i<=c;++i)
for(int j=-;j<=;++j)
for(int k=-;k<=;++k)
if(j||k)
{
int x=p[i].x+j,y=p[i].y+k;
if(x<=||y<=||x>n||y>m||mp.Check(x,y)) continue;
mp.ins(x,y);q[Cnt]=P(x,y);
}
for(int i=,k;i<=Cnt;++i)
for(int j=;j<;++j)
{
int x=q[i].x+dis[j][],y=q[i].y+dis[j][];
if(x<=||y<=||x>n||y>m||(k=mp.Check(x,y))<=) continue;
ins(i,k);
}
} void tj(int x,int fa)
{
dfn[x]=low[x]=++dn;bel[x]=tot;Cut[x]=;int son=;
for(int i=head[x];i;i=e[i].next)if(e[i].to!=fa)
{
if(!dfn[e[i].to])
{
++son,tj(e[i].to,x),low[x]=min(low[x],low[e[i].to]);
if(low[e[i].to]>=dfn[x]) Cut[x]=;
}
else low[x]=min(low[x],dfn[e[i].to]);
}
if(son==&&!fa) Cut[x]=;
} bool Round(int id)
{
for(int i=-;i<=;++i)
for(int j=-;j<=;++j)
if(i||j)
{
int x=q[id].x+i,y=q[id].y+j;
if(x&&y&&mp.Check(x,y)<)return ;
}
return ;
} bool check(int t)
{
int col=-;
for(int l=;l<V[t].size();++l)
{
int X=p[V[t][l]].x,Y=p[V[t][l]].y;
for(int i=-;i<=;++i)
for(int j=-,k;j<=;++j)
if(i||j)
{
int x=X+i,y=Y+j;
if(x<||y<||x>n||y>m||(k=mp.Check(x,y))<) continue;
if(col==-) col=bel[k];
else if(col!=bel[k]) return true;
}
}
return false;
} void Dfs(int x)
{
col[x]=Col;V[Col].push_back(x);
for(int j=;j<v[x].size();++j)
if(!col[v[x][j]]) Dfs(v[x][j]);
} int main()
{
for(int T=read();T;--T)
{
n=read();m=read();c=read();ans=;mp.clear();
if(m==||n==) ans=;Cnt=-c-;
for(int i=;i<=c;++i)
p[i].x=read(),p[i].y=read(),mp.ins(p[i].x,p[i].y);
if(Check()) puts("-1");
else
{
Cnt=;en=;tot=;dn=;Col=;build();
for(int i=,k;i<=c;++i)
for(int j=;j<;++j)
{
int x=p[i].x+dis[j][],y=p[i].y+dis[j][];
if(x<||y<||x>n||y>m) continue;
if((k=mp.Check(x,y))<) v[i].push_back(k+c+);
}
for(int i=;i<=c;++i)
if(!col[i]) ++Col,Dfs(i);
for(int i=;i<=Cnt;++i)
if(!dfn[i]) ++tot,tj(i,);
for(int i=;i<=Cnt&&ans>;++i) if(Cut[i]&&Round(i)) ans=;
for(int i=;i<=Col&&ans;++i)
if(check(i)) ans=;
printf("%d\n",ans);
memset(head,,sizeof(int)*(Cnt+));
for(int i=;i<=c;++i) v[i].clear(),V[i].clear();
memset(dfn,,sizeof(int)*(Cnt+));
memset(low,,sizeof(int)*(Cnt+));
memset(col,,sizeof(int)*(c+));
}
}
return ;
}
[Noi2016]网格的更多相关文章
- [UOJ#220][BZOJ4651][Noi2016]网格
[UOJ#220][BZOJ4651][Noi2016]网格 试题描述 跳蚤国王和蛐蛐国王在玩一个游戏. 他们在一个 n 行 m 列的网格上排兵布阵.其中的 c 个格子中 (0≤c≤nm),每个格子有 ...
- 洛谷P1173 [NOI2016]网格
这个码量绝对是业界大毒瘤...... 300行,6.5k,烦的要死...... 题意:给你一个网格图,里面有0或1.你需要把一些0换成1使得存在某两个0不四联通.输出最小的换的数量.无解-1. n,m ...
- [BZOJ4651][NOI2016]网格(Tarjan)
下面直接给出结论,相关证明见官方题解. 1.若跳蚤数不超过1或仅有两只跳蚤且相邻,则答案为-1. 2.若跳蚤形成的连通块个数大于1,则答案为0. 3.若跳蚤之间建图存在割点,则答案为1. 4.否则为2 ...
- BZOJ4651 & 洛谷1173 & UOJ220:[NOI2016]网格——题解(附debug数据)
https://www.lydsy.com/JudgeOnline/problem.php?id=4651 https://www.luogu.org/problemnew/show/P1173#su ...
- BZOJ4651/UOJ220 [Noi2016]网格
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
- 并不对劲的bzoj4651:loj2084:uoj220:p1173:[NOI2016]网格
题目大意 有一个\(n*m\)(\(n,m\leq10^9\))的网格,每个格子是空地或障碍(\(障碍数\leq10^5\)) 定义两块空地连通,当且仅当它们是"相邻的两块空地"或 ...
- BZOJ4651 NOI2016网格(割点)
首先显然可以通过孤立角落里的跳蚤使其不连通,所以只要有解答案就不会大于2.同样显然的一点是当且仅当跳蚤数量<=2且连通时无解.做法其实也很显然了:特判无解,若跳蚤不连通输出0,否则看图中是否无割 ...
- UOJ220 [NOI2016] 网格 【割顶】【并查集】
题目分析: 答案显然只有{-1,0,1,2}四种. 对于答案等于-1的情况,只有两种情况,一种是只剩一只跳蚤,另一种是只剩两只跳蚤且他们四连通,这个很好判. 对于答案等于0的情况,那说明联通块大于1, ...
- NOI2016
luoguP1712 [NOI2016]区间 这是一道送分题. 对于我这种每天抄题解不动脑子思维僵化得厉害的智障选手就是送命题. 一直在想端点排序各种Treap搞... 正解: 已知一些区间,如何判断 ...
随机推荐
- 《javascript设计模式与开发实践》阅读笔记(14)—— 中介者模式
中介者模式 数个对象之间的通信全部委托一个中介者完成.适用于对象之间互相引用,关系错综复杂的情况. 什么情况下需要使用中介者模式 对象较多,且对象间会相互引用,当一个对象的某个状态改变时,得通知其他对 ...
- float、absolute、inline-block三者区别
0.前言 float属性在css2中是一个热门的属性,被广泛应用于布局之中,同时由于不当使用float带来的问题也非常多,本文结合自己对float的理解以及实际项目中碰到float的相关问题,做一个详 ...
- 用nodejs 开发的智能提示
用nodejs 开发的智能提示 时间:2014-07-01 03:50:18 类别:搜索引擎 访问: 2576 次 感谢:http://lutaf.com/223.htm 智能提示对于搜索非常重要,相 ...
- 在windows环境下安装redis和phpredis的扩展
在windows环境下安装redis和phpredis的扩展 1.首先配置php: 需要在windows的集成环境中找到php的扩展文件夹,ext,然后在网上寻找自己的php对应的.dll文件 比如说 ...
- node防xss攻击插件
var xss = require('node-xss').clean; router.post("/orders/insert-orders", function (req, r ...
- 写一个vue组件
写一个vue组件 我下面写的是以.vue结尾的单文件组件的写法,是基于webpack构建的项目.如果还不知道怎么用webpack构建一个vue的工程的,可以移步到vue-cli. 一个完整的vue组件 ...
- 阿里云API网关(4)快速入门(开放 API)
网关指南: https://help.aliyun.com/document_detail/29487.html?spm=5176.doc48835.6.550.23Oqbl 网关控制台: https ...
- maven入门(8)maven的依赖管理
我们项目中用到的jar包可以通过依赖的方式引入,构建项目的时候从Maven仓库下载即可. 1. 依赖配置 依赖可以声明如下: <project> ... <dependenci ...
- git常用命令行总结
Git是当今最流行的版本控制工具.这几年GitHub也干掉了GoogleCode和Sourceforge,从三大代码仓库中脱颖而出,除了GitHub自身的优秀外,Git也是功不可没. 为何Git如此出 ...
- Python学习之dict和set
#coding=utf-8 # dict dict= {'bob': 40, 'andy': 30} print dict['bob'] # 通过dict提供的get方法,如果key不存在,可以返回N ...