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

则询问(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. 介绍C++11标准的变长参数模板

    目前大部分主流编译器的最新版本均支持了C++11标准(官方名为ISO/IEC14882:2011)大部分的语法特性,其中比较难理解的新语法特性可能要属变长参数模板(variadic template) ...

  2. bzoj千题计划226:bzoj2763: [JLOI2011]飞行路线

    http://www.lydsy.com/JudgeOnline/problem.php?id=2763 这也算分层图最短路? dp[i][j]到城市i,还剩k次免费次数的最短路 #include&l ...

  3. 给定一个整数,求解该整数最少能用多少个Fib数字相加得到

    一,问题描述 给定一个整数N,求解该整数最少能用多少个Fib数字相加得到 Fib数列,就是如: 1,1,2,3,5,8,13.... Fib数列,满足条件:Fib(n)=Fib(n-1)+Fib(n- ...

  4. [转载]Supporting OData $inlinecount with the new Web API OData preview package

    http://www.strathweb.com/2012/08/supporting-odata-inlinecount-with-the-new-web-api-odata-preview-pac ...

  5. Django进阶之session

    基于cookie做用户验证时:敏感信息不适合放在cookie中 session依赖cookie session原理 cookie是保存在用户浏览器端的键值对 session是保存在服务器端的键值对 s ...

  6. 以python代码解释fork系统调用

    import os print('Process (%s) start...' % os.getpid()) # Only works on Unix/Linux/Mac: pid = os.fork ...

  7. Servlet笔记10--Session

    Web编程中的Session: 代码示例: package com.bjpowernode.javaweb.servlet; import java.io.IOException; import ja ...

  8. Git GUI可视化操作教程

    1.在本地新建版本库 首先,我们打开Git GUI是这样的一个界面,选择第一项,新建版本库.  然后选择你需要进行版本管理的项目路径,我选择了一个LoginDemo的项目.  当你创建了版本库的时候, ...

  9. 字符串前面加u、r、b的含义

    u/U:表示unicode字符串 不是仅仅是针对中文, 可以针对任何的字符串,代表是对字符串进行unicode编码. 一般英文字符在使用各种编码下, 基本都可以正常解析, 所以一般不带u:但是中文, ...

  10. LeetCode(14):最长公共前缀

    Easy! 题目描述: 编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower",&qu ...