「BZOJ4242」水壶
题目链接
\(Solution\)
我们看到这题之后发现这题不是\(n^2\)把边弄出来后就跟货车运输差不多了,但是看了数据后发现\(n^2\)条边建不出来啊,这里就不详细的讲\(kruskal\)重构树了,只讲怎么建边
所以我们要考虑怎么优化这个建边方式
显然这里不可以用什么线段树,倍增,前后缀什么的来优化。
所以我们应该考虑怎么减少需要边的数量。
我们可以很容易的发现在这\(n^2\)条边中有些是可以不用的。
举个栗子:
我们三个点\(x,y,z\)
\(x\)到\(y\)有一条\(1\)的边
\(y\)到\(z\)有一条\(1\)的边
\(x\)到\(z\)有一条\(2\)的边
可以发现\(x\)到\(z\)的边没有意义,我们可以通过\(x\)到\(y\)再到\(z\),这样子显然不会影响答案
我们考虑怎么不建立这些无意义的边。
可以先把每个建筑加入队列,跑\(bfs\).如果在拓展一个建筑的“势力范围”时发现这个点已经被“占领”了,这个点肯定在连接两个建筑的最短路径上.于是在这里给这两个建筑建边即可。
至于实现,留作课后作业.
然后在康康边权,这个可以用一个\(vector\)存,这样就不用\(sort\)了。但是我\(sort\)也过了
\(Code\)
#include<bits/stdc++.h>
#define file(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);
using namespace std;
const int N=4e5+10;
int read(){
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9') f=(c=='-')?-1:1,c=getchar();
while(c>='0'&&c<='9') x=x*10+c-48,c=getchar();
return f*x;
}
struct node1 {
int to,next;
}e[1000001];
struct node{
int x,y,v;
}b[N*50];
int res,cnt,n,m,t,pre[N],head[N],vis[N],W,H,Q,P,x,y;
int f[N][21],dep[N],val[N],bin[101];
int Vis[2010][2010],bj[2010][2010];
char Map[2010][2010];
void add(int x,int y){ e[++cnt].to=y,e[cnt].next=head[x],head[x]=cnt; }
int find(int x){ return pre[x]==x?x:pre[x]=find(pre[x]); }
bool cmp(const node & a , const node & b ){ return a.v<b.v; }
void dfs(int k){
vis[k]=1;
for(int j=1;j<=20;j++)
f[k][j]=f[f[k][j-1]][j-1];
for(int i=head[k];i;i=e[i].next){
int v=e[i].to;
f[v][0]=k,dep[v]=dep[k]+1;
dfs(v);
}
}
int lca(int x,int y){
if(dep[x]<dep[y])
swap(x,y);
for(int i=20;i>=0;i--)
if(dep[x]-(1<<i)>=dep[y])
x=f[x][i];
if(x==y)
return y;
for(int i=20;i>=0;i--){
if(f[x][i]==f[y][i]||!f[y][i]||!f[x][i])
continue;
x=f[x][i],y=f[y][i];
}
return f[x][0];
}
void build(){
res=n,sort(b+1,b+1+m,cmp);
for(int i=1;i<=m;i++){
int fx=find(b[i].x),fy=find(b[i].y);
if(fx!=fy)
val[++res]=b[i].v,pre[fx]=res,pre[fy]=res,add(res,fx),add(res,fy);
if(res==n*2-1)
break;
}
}
struct node2{
int id,x,y,v;
};
queue<node2> q;
int fx[10]={0,0,0,-1,1};
int fy[10]={0,1,-1,0,0};
void bfs(){
for(int i=1;i<=n;i++)
x=read(),y=read(),q.push((node2){i,x,y,0}),Vis[x][y]=i;
while(!q.empty()){
node2 now=q.front();
q.pop();
for(int i=1;i<=4;i++){
int x=now.x+fx[i],y=now.y+fy[i];
if(x<1||y<1||x>H||y>W||Map[x][y]=='#') continue;
if(Vis[x][y]) b[++m].x=now.id,b[m].y=Vis[x][y],b[m].v=now.v+bj[x][y];
else Vis[x][y]=now.id,bj[x][y]=now.v+1,q.push((node2){now.id,x,y,now.v+1});
}
}
}
int main(){
bin[1]=0,H=read(),W=read(),n=read(),Q=read();
for(int i=1;i<=H;i++)
scanf("%s",Map[i]+1);
for(int i=1;i<=n*2;i++) pre[i]=i;
for(int i=1;i<=20;i++) bin[i]=bin[i-1]<<1;
bfs();
build();
for(int i=1;i<=n;i++)
if(!vis[i])
dfs(find(i));
while(Q--){
int x=read(),y=read(),p=lca(x,y);
if(p==0)
cout<<"-1\n";
else
cout<<val[p]<<endl;
}
}
「BZOJ4242」水壶的更多相关文章
- 「译」JUnit 5 系列:条件测试
原文地址:http://blog.codefx.org/libraries/junit-5-conditions/ 原文日期:08, May, 2016 译文首发:Linesh 的博客:「译」JUni ...
- 「译」JUnit 5 系列:扩展模型(Extension Model)
原文地址:http://blog.codefx.org/design/architecture/junit-5-extension-model/ 原文日期:11, Apr, 2016 译文首发:Lin ...
- JavaScript OOP 之「创建对象」
工厂模式 工厂模式是软件工程领域一种广为人知的设计模式,这种模式抽象了创建具体对象的过程.工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题. function createPers ...
- 「C++」理解智能指针
维基百科上面对于「智能指针」是这样描述的: 智能指针(英语:Smart pointer)是一种抽象的数据类型.在程序设计中,它通常是经由类型模板(class template)来实做,借由模板(tem ...
- 「JavaScript」四种跨域方式详解
超详细并且带 Demo 的 JavaScript 跨域指南来了! 本文基于你了解 JavaScript 的同源策略,并且了解使用跨域跨域的理由. 1. JSONP 首先要介绍的跨域方法必然是 JSON ...
- 「2014-5-31」Z-Stack - Modification of Zigbee Device Object for better network access management
写一份赏心悦目的工程文档,是很困难的事情.若想写得完善,不仅得用对工具(use the right tools),注重文笔,还得投入大把时间,真心是一件难度颇高的事情.但,若是真写好了,也是善莫大焉: ...
- 「2014-3-18」multi-pattern string match using aho-corasick
我是擅(倾)长(向)把一篇文章写成杂文的.毕竟,写博客记录生活点滴,比不得发 paper,要求字斟句酌八股结构到位:风格偏杂文一点,也是没人拒稿的.这么说来,arxiv 就好比是 paper 世界的博 ...
- 「2014-3-17」C pointer again …
记录一个比较基础的东东-- C 语言的指针,一直让人又爱又恨,爱它的人觉得它既灵活又强大,恨它的人觉得它太过于灵活太过于强大以至于容易将人绕晕.最早接触 C 语言,还是在刚进入大学的时候,算起来有好些 ...
- 「2014-3-13」Javascript Engine, Java VM, Python interpreter, PyPy – a glance
提要: url anchor (ajax) => javascript engine (1~4 articles) => java VM vs. python interpreter =& ...
随机推荐
- UVA571Jugs题解--简单数论(其实是瞎搞)
题目链接 https://cn.vjudge.net/problem/UVA-571 分析 刚做了道倒水问题的题想看看能不能水二倍经验,结果发现了这道题 题意翻译:https://www.cnblog ...
- 向PHP发送HTTP-Post请求
欢迎访问我的个人博客,获取更多有用的东西 链接一 链接二 也可以关注我的微信订阅号:CN丶Moti 1.post.html <!DOCTYPE html> <html lang=&q ...
- Javascript 中apply call bind
在 javascript 中,call 和 apply 都是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为了改变函数体内部 this 的指向. 先来一个例子: functi ...
- 基于MQTT的串口数据转发器
问: ComHub能做什么?ComHub使用MQTT协议,将串口数据经TCP分发出去.这种结构可以实现很多功能:1.COM-Over-TCP: 将COM数据使用TCP远程传送;2.COM多播:一个CO ...
- [AWS - EC2] 如何向 Amazon Linux 2 实例传输文件,下载文件。How to send/ download files from Amazon Linux 2 Instance
1. 需要: 安装 WinSCP 2. 需要: PuTTY 生成的ppk格式密钥, 没有的话请移步此文章,完成1, 2, 3步即可. 3. 打开 WinSCP , 如果提示已经有PuTTY配置是否导入 ...
- 复杂sql优化步骤与技巧
数据管理型系统,由于用户的要求或者系统设计要求,会出现大量表进行join,还要进行大量统计性数据查询展示,甚至数据权限控制等操作.最后会导致sql异常复杂,随着数据量增加,或者只是应用到生产环境(正式 ...
- sql like 拼接字符串模糊查询
这种分割的值大家常用,如果要用like 来查询包含2,这个值的数据有哪些,这个怎么查? like '%2%' ????,这是不行的如果是 44,125,687 同样可以查出来,那么就想到通配符, l ...
- unzip解压3G或者4G以上文件失败的解决方法
Linux下,使用unzip解压时,报错:End-of-central-directory signature not found. Either this file is nota zipfile ...
- kotlin的loop和Range、list和map
继续学习Kolin的基础语法,比较简单,直接练习代码.loop和range: 这里用一个场景来说明:计算从1到100之间数的总和,那在kotlin中是如何搞的呢? 上面这么简单的一句代码确实是能表达么 ...
- QOpenGLWidget
QOpenGLWidget描述 QOpenGLWidget类是用于渲染OpenGL图形. 除了可以选择使用QPainter和标准的OpenGL渲染图形,QOpenGLWidget类提供了在Qt应用程序 ...