对于任意两个建筑物,以它们之间的最短路为边权求出最小生成树。

则询问(x,y)的答案为最小生成树上x到y路径上边权的最大值。

BFS求出离每个点最近的建筑物以及到它的距离,可以发现只有交界处的边才有用,用这些边求MST即可。

#include<cstdio>
#include<algorithm>
using namespace std;
const int L=2010,N=200010,K=17,inf=~0U>>1;
int H,W,n,m,Q,i,j,x,y,z,p,mx;
int dis[L][L][2],q[L*L][2],h=1,t;
int fa[N],g[N],v[N<<1],w[N<<1],nxt[N<<1],ed,f[N][K+1],fm[N][K+1],d[N];
char s[L];bool a[L][L],vis[L][L];
struct E{int x,y;E*nxt;}*e[L*L],pool[L*L],*cur=pool;
inline void up(int&a,int b){if(a<b)a=b;}
inline void bfs(int x,int y,int z,int p){
if(x<1||x>H||y<1||y>W||vis[x][y]||!a[x][y])return;
vis[x][y]=1,dis[x][y][0]=z,dis[x][y][1]=p,q[++t][0]=x,q[t][1]=y;
}
inline void check(int a,int b,int c,int d){
if(vis[a][b]&&vis[c][d]&&dis[a][b][1]!=dis[c][d][1]){
int x=dis[a][b][0]+dis[c][d][0];
E*p=cur++;p->x=dis[a][b][1];p->y=dis[c][d][1];p->nxt=e[x];e[x]=p;
up(mx,x);
}
}
int F(int x){return fa[x]==x?x:fa[x]=F(fa[x]);}
inline void add(int x,int y,int z){v[++ed]=y;w[ed]=z;nxt[ed]=g[x];g[x]=ed;}
void dfs(int x,int pre,int dis){
f[x][0]=pre,fm[x][0]=dis;d[x]=d[pre]+1;
for(int i=1;i<=K;i++)f[x][i]=f[f[x][i-1]][i-1],fm[x][i]=max(fm[x][i-1],fm[f[x][i-1]][i-1]);
for(int i=g[x];i;i=nxt[i])if(v[i]!=pre)dfs(v[i],x,w[i]);
}
inline int ask(int x,int y){
if(F(x)!=F(y))return -1;
int t=0,i;
if(d[x]<d[y])swap(x,y);
for(i=K;~i;i--)if(d[f[x][i]]>=d[y])up(t,fm[x][i]),x=f[x][i];
if(x==y)return t;
for(i=K;~i;i--)if(f[x][i]!=f[y][i])up(t,max(fm[x][i],fm[y][i])),x=f[x][i],y=f[y][i];
return max(t,max(fm[x][0],fm[y][0]));
}
inline void read(int&a){char ch;while(!(((ch=getchar())>='0')&&(ch<='9')));a=ch-'0';while(((ch=getchar())>='0')&&(ch<='9'))(a*=10)+=ch-'0';}
int main(){
read(H),read(W),read(n),read(Q);
for(i=1;i<=H;i++)for(scanf("%s",s+1),j=1;j<=W;j++)a[i][j]=s[j]=='.';
for(i=1;i<=n;i++)read(x),read(y),bfs(x,y,0,i),fa[i]=i;
while(h<=t){
x=q[h][0],y=q[h++][1],z=dis[x][y][0]+1,p=dis[x][y][1];
bfs(x-1,y,z,p),bfs(x+1,y,z,p),bfs(x,y-1,z,p),bfs(x,y+1,z,p);
}
for(i=1;i<=H;i++)for(j=1;j<W;j++)check(i,j,i,j+1);
for(i=1;i<H;i++)for(j=1;j<=W;j++)check(i,j,i+1,j);
for(i=0;i<=mx;i++)for(E*p=e[i];p;p=p->nxt)if(F(p->x)!=F(p->y))add(p->x,p->y,i),add(p->y,p->x,i),fa[fa[p->x]]=fa[p->y];
for(i=1;i<=n;i++)if(!d[i])dfs(i,0,0);
while(Q--)read(x),read(y),printf("%d\n",ask(x,y));
return 0;
}

  

BZOJ4242 : 水壶的更多相关文章

  1. BFS+最小生成树+倍增+LCA【bzoj】4242 水壶

    [bzoj4242 水壶] Description JOI君所居住的IOI市以一年四季都十分炎热著称. IOI市是一个被分成纵H*横W块区域的长方形,每个区域都是建筑物.原野.墙壁之一.建筑物的区域有 ...

  2. 【BZOJ4242】水壶(克鲁斯卡尔重构树,BFS)

    [BZOJ4242]水壶(克鲁斯卡尔重构树,BFS) 题面 BZOJ然而是权限题. Description JOI君所居住的IOI市以一年四季都十分炎热著称. IOI市是一个被分成纵H*横W块区域的长 ...

  3. 最小生成树Kruskal+LCA+bfs【bzoj4242】水壶

    Description JOI 君所居住的 IOI 市以一年四季都十分炎热著称. IOI 市被分成 \(H\) 行,每行包含 \(W\) 块区域.每个区域都是建筑物.原野.墙壁之一. IOI 市有 \ ...

  4. 【bzoj4242】水壶 BFS+最小生成树+倍增LCA

    题目描述 JOI君所居住的IOI市以一年四季都十分炎热著称. IOI市是一个被分成纵H*横W块区域的长方形,每个区域都是建筑物.原野.墙壁之一.建筑物的区域有P个,编号为1...P. JOI君只能进入 ...

  5. 「BZOJ4242」水壶

    题目链接 戳我 \(Solution\) 我们看到这题之后发现这题不是\(n^2\)把边弄出来后就跟货车运输差不多了,但是看了数据后发现\(n^2\)条边建不出来啊,这里就不详细的讲\(kruskal ...

  6. [Swift]LeetCode365. 水壶问题 | Water and Jug Problem

    You are given two jugs with capacities x and y litres. There is an infinite amount of water supply a ...

  7. loj2876 水壶 [JOISC 2014 Day2] kruscal重构树

    正解:kruscal重构树+bfs 解题报告: 我永远喜欢loj! 感觉这题和这题挺像的,,,预处理和解题方法都是,,,所以大概整体二分能过去? 但因为做这题主要是入门一下kruscal重构树,,,所 ...

  8. 水壶-[Kruskal重构树] [解题报告]

    水壶 本来从不写针对某题的题解,但因为自己实在是太蠢了,这道题也神TM的恶心,于是就写篇博客纪念一下 H水壶 时间限制 : 50000 MS 空间限制 : 565536 KB 评测说明 : 2s,51 ...

  9. BZOJ 4242 水壶(BFS建图+最小生成树+树上倍增)

    题意 JOI君所居住的IOI市以一年四季都十分炎热著称. IOI市是一个被分成纵H*横W块区域的长方形,每个区域都是建筑物.原野.墙壁之一.建筑物的区域有P个,编号为1...P. JOI君只能进入建筑 ...

随机推荐

  1. css3 :nth-child()选择器的使用

    一.nth-child() 1. nth-child(n):父元素下的第n个子元素,n>0,索引从1开始.不区分子元素类型. 2. nth-child(odd):父元素下的奇数子元素,等同于:n ...

  2. Spark记录-Scala循环语句

    Scala while循环语句 当给定条件为真时,while循环重复一个语句或一组语句.它在执行循环体之前测试条件状态. 只要给定的条件为真,while循环语句重复执行目标语句. object Dem ...

  3. MongoDB 聚合嵌入的数组(扁平化数据+管道)

    MongoDB学习教程 先看下要操作的主要数据结构: { "_id" : "000015e0-3e9c-40b3-bd0d-6e7949f455c0", &qu ...

  4. linux下搭建我的世界spongeforge 服务器 (海绵端)

    以下我用的都是1.10.2版本 且以下用的服务器连接管理软件有WinSCP.Xshell 5 首先,去下载一个MC1.10.2的纯净服务端,这个不会很难,百度一下! 比如我下的文件就叫minecraf ...

  5. mybatis一对一关联查询——(八)

    1.需求 查询所有订单信息,关联查询下单用户信息. 注意: 因为一个订单信息只会是一个人下的订单,所以从查询订单信息出发关联查询用户信息为一对一查询.如果从用户信息出发查询用户下的订单信息则为一对多查 ...

  6. keepalived启动不成功,状态一直是inactive(dead) 的解决办法以及keepalived高版本没有rc.d目录,虚拟VIP无法访问问题

    安装配置教程我就不说了,网上很多,这里只给出我遇到的两个坑: 1 rc.d目录 ,kp在1.4版本之后rc.d要去解压之后的源码包里去找,make之后的目录里面没有了,我使用的是2.0.13最新版本, ...

  7. 各种initcall的执行先后顺序(module_init、postcore_initcall、arch_initcall、subsys_initcall、 fs_initcall)【转】

    转自:http://www.cnblogs.com/superlcc/archive/2012/09/12/2681930.html 现在以module_init为例分析initcall在内核中的调用 ...

  8. oracle列转行

    unpivot()函数需要Oracle版本大于等于11g --创建表 create table Fruit(id int,name varchar(20), Q1 int, Q2 int, Q3 in ...

  9. 使用maven命令终端构建一个web项目及发布该项目

    构建环境: maven版本:3.3.9 系统平台:Windows7 x64 JDK版本:1.7 构建步骤: 1.打开maven安装目录,在地址栏输入cmd进入命令窗口 2.输入命令mvn archet ...

  10. 004_on-my-zsh漂亮的shell

    一. http://www.cnblogs.com/GarveyCalvin/p/4301235.html 二. 前言:Zsh可配置性强,用户可以自定义配置,个性化强.Zsh tab补全更强大,该功能 ...