[Noi2016]网格
来自FallDream的博客,未经允许,请勿转载,谢谢。
跳蚤国王和蛐蛐国王在玩一个游戏。
表示一只跳蚤,用图
表示一只蛐蛐,那么图 1 描述了一个 n=4,m=4,c=2的情况。
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搞... 正解: 已知一些区间,如何判断 ...
随机推荐
- 为label或者textView添加placeHolder
Tip:使用textView的代理需要在头文件中加入: <UITextViewDelegate> h文件 @interface FeedbackViewController : UIVie ...
- 18-TypeScript模板方法模式
在有些情况下,一个功能在基础功能上是不会变的,算法的基本骨架也是确定的,但是在某些场景下算法的具体实现有些差异.应对这种问题,可以采用模板方法模式: abstract class Salary{ ab ...
- CSS揭秘(三)形状
Chapter 3 1. 椭圆 椭圆的实现主要依靠 border-radius 属性,该属性确定边框切圆角的半径大小,可以指定数值 px,也可以使用百分比显示 而且该属性非常灵活,四个角可以分别设置 ...
- vue组件详解(四)——使用slot分发内容
一.什么是slot 在使用组件时,我们常常要像这样组合它们: <app> <app-header></app-header> <app-footer>& ...
- Apollo单向SSL认证(2)
一.生成ks和ts 二.连接测试 1.配置 2.测试
- Spring Security 入门(3-11)Spring Security 的登录密码验证过程 UsernamePasswordAuthenticationFilter
认证过程如下 一.先判断请求(请求必须是post请求)地址是否为配置的 login-processing-url 值(默认/j_spring_security_check),如果不是,则放行,进入下一 ...
- EasyUI combobox下拉多选框的实现
combobox实现下拉列表多选, 效果如下
- 详解Ajax请求(四)——多个异步请求的执行顺序
首先提出一个问题:点击页面上一个按钮发送两个ajax请求,其中一个请求会不会等待另一个请求执行完毕之后再执行? 答案是:不会,这两个异步请求会同时发送,至于执行的快与慢,要看响应的数据量的大小及后台逻 ...
- 访问器属性:setter()函数和getter()函数
1.干嘛用的? getter()函数:返回有效的值 setter()函数:调用它并传入数据,这个函数决定如何处理数据 2.具备哪些属性?如何定义? configurable(默认为true),enum ...
- JavaScript中的 原型 property 构造函数 和实例对象之间的关系
1 为什么要使用原型? /* * javascript当中 原型 prototype 对象 * * */ //首先引入 prototype的意义,为什么要使用这个对象 //先来写一个构造函数的面向对象 ...