BZOJ 4242: 水壶 Kruskal+BFS
4242: 水壶
Time Limit: 40 Sec Memory Limit: 256 MB
Submit: 427 Solved: 112
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
.....
..##.
.#...
..#..
.....
1 1
4 2
3 3
2 5
1 2
2 4
1 3
3 4
Sample Output
4
4
2
HINT
Source
JOI 2013~2014 春季training合宿 竞技2 By PoPoQQQ
朴素的暴力:得到任意两点的间的最短距离,然后kruskal。因为是求最大值,所以可以直接用并查集(按秩合并)上的路径最值。树高为O(logP)。共O(P*W*H)
考虑慢慢增加每个建筑物连出去的边权,这个和Kruskal很相似。然后又一个朴素的想法,搞P个队列,同时扩展。碰到一个建筑物才停下来并不扩展这个建筑物,合并这个两个建筑物。O(P*W*H)
既然是同时扩展,那么边权肯定都一样。那么碰到一个已经被扩展的点就可以将距离加起来,用来更新当成这个两个建筑物的距离。边权都*2肯定还是满足kruskal的算法。一个点最多被碰四次。O(W*H*4)
细节:可能边权并没有*2,而是一个奇一个偶,可能会影响同一种边权的kruskal加边顺序,所以我把这些边都存下来......
然后求一发Kruskal就可以了。
#include<cstdio>
#include<cstring>
#include<algorithm> const int HW(),len(),N();
const int dx[]={,,-,};
const int dy[]={-,,,};
int O[HW][HW],last[HW][HW],dis[HW][HW],H,W,P,Q;
struct Palce{int x,y;}q[N+],now; int l,h;
char ch[HW];int x,y;
struct Node{int a,b,c;}bot[N+];int top;
int f[len+],cost[len+],rank[len+],depth[len+]; bool cmp(Node A,Node B){return A.c<B.c;}
int max(int a,int b){return a>b?a:b;}
template <class T>void read(T &x)
{
x=;int f=; char ch=getchar();
while(ch<''||ch>''){f=(ch=='-');ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
x=f?-x:x;
} int gf(int x){return x==f[x]?x:gf(f[x]);}
int gf_d(int x)
{
int d; for(d=;x!=f[x];x=f[x])d++;
return d;
}
void swap(int &a,int &b){if(a==b)return;a^=b;b^=a;a^=b;}
void union_fa(int x,int y,int d)
{
x=gf(x),y=gf(y); if(x==y)return;
if(rank[x]>rank[y]) swap(x,y);
if(rank[x]==rank[y]) rank[y]++;
f[x]=y; cost[x]=d;
}
void BFS()
{
h=;
while(h<l)
{
now=q[++h];
for(int d=;d<;d++)
if(O[now.x+dx[d]][now.y+dy[d]])
{
if(last[now.x+dx[d]][now.y+dy[d]]&&last[now.x+dx[d]][now.y+dy[d]]!=last[now.x][now.y])
bot[++top]=(Node){last[now.x+dx[d]][now.y+dy[d]],last[now.x][now.y],dis[now.x+dx[d]][now.y+dy[d]]+dis[now.x][now.y]};
else
if(!dis[now.x+dx[d]][now.y+dy[d]])
{
dis[now.x+dx[d]][now.y+dy[d]]=dis[now.x][now.y]+;
last[now.x+dx[d]][now.y+dy[d]]=last[now.x][now.y];
q[++l]=(Palce){now.x+dx[d],now.y+dy[d]};
}
}
}
}
int jump(int x,int y)
{
int d=;
if(depth[x]<depth[y])swap(x,y);
for(;depth[x]!=depth[y];)d=max(d,cost[x]),x=f[x];
for(;x!=y;)d=max(d,cost[x]),d=max(d,cost[y]),x=f[x],y=f[y];
return d;
}
int main()
{
// freopen("C.in","r",stdin);
// freopen("C.out","w",stdout);
read(H),read(W);
read(P),read(Q);
for(int i=;i<=H;i++)
{
scanf("%s",ch+);
for(int j=;j<=W;j++)O[i][j]=(ch[j]!='#');
}
for(int i=;i<=P;i++)
{
read(x),read(y); f[i]=i; rank[i]=;
last[x][y]=i; q[++l]=(Palce){x,y};
}
BFS();//O(H*W)
std::sort(bot+,bot++top,cmp);
for(int i=;i<=top;i++)
union_fa(bot[i].a,bot[i].b,bot[i].c);//按kruskal走,那么两个连通块之间的过往最大值就是这条边,所以可以直接在并查集的树上求最值。
for(int i=;i<=P;i++)depth[i]=gf_d(i);//O(PlogP)
for(int i=;i<=Q;i++)
{
read(x);read(y);
if(gf(x)!=gf(y))printf("-1\n");
else printf("%d\n",jump(x,y));//O(logP)
}
return ;
}
BZOJ 4242: 水壶 Kruskal+BFS的更多相关文章
- bzoj 4242 水壶 (多源最短路+最小生成树+启发式合并)
4242: 水壶 Time Limit: 50 Sec Memory Limit: 512 MBSubmit: 1028 Solved: 261[Submit][Status][Discuss] ...
- BZOJ 4242: 水壶(Kruskal重构树 + Bfs)
题意 一块 \(h ∗ w\) 的区域,存在障碍.空地.\(n\) 个建筑,从一个建筑到另一个建筑的花费为:路径上最长的连续空地的长度. \(q\) 次询问:从建筑 \(s_i\) 到 \(t_i\) ...
- BZOJ 4242 水壶(BFS建图+最小生成树+树上倍增)
题意 JOI君所居住的IOI市以一年四季都十分炎热著称. IOI市是一个被分成纵H*横W块区域的长方形,每个区域都是建筑物.原野.墙壁之一.建筑物的区域有P个,编号为1...P. JOI君只能进入建筑 ...
- BFS+最小生成树+倍增+LCA【bzoj】4242 水壶
[bzoj4242 水壶] Description JOI君所居住的IOI市以一年四季都十分炎热著称. IOI市是一个被分成纵H*横W块区域的长方形,每个区域都是建筑物.原野.墙壁之一.建筑物的区域有 ...
- 水壶-[Kruskal重构树] [解题报告]
水壶 本来从不写针对某题的题解,但因为自己实在是太蠢了,这道题也神TM的恶心,于是就写篇博客纪念一下 H水壶 时间限制 : 50000 MS 空间限制 : 565536 KB 评测说明 : 2s,51 ...
- BZOJ 1086 王室联邦 | BFS
BZOJ 1086 王室联邦 题意 把一棵树分块,每块大小在[B, 3B]之间(B由输入数据给出),每个块需要对应一个核心点,核心点可以在块内,这个点要满足块内每个点到核心点的路径上的点都属于这个块( ...
- [bzoj 3732] Network (Kruskal重构树)
kruskal重构树 Description 给你N个点的无向图 (1 <= N <= 15,000),记为:1-N. 图中有M条边 (1 <= M <= 30,000) ,第 ...
- bzoj 1098 poi2007 办公楼 bfs+链表
题意很好理解,求给出图反图的联通块个数. 考虑这样一个事情:一个联通块里的点,最多只会被遍历一次,再遍历时没有任何意义 所以用链表来存,每遍历到一个点就将该点删掉 #include<cstdio ...
- BZOJ 1295 最长距离 BFS+枚举
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1295 题目大意: windy有一块矩形土地,被分为 N*M 块 1*1 的小格子. 有 ...
随机推荐
- Jmeter JDBC Request 中文乱码问题
在JDBC Request的SQL Query的编辑器输入中文会乱码,导入插入数据库的内容也是乱码,如下图 解决办法:JDBC Connection Configuration的Database UR ...
- 了解protected 以及公用、私有和受保护的继承
protected成员 可以认为protected访问标号是private 和public 的混合: 1.像private成员一样,protected成员不能被类的用户访问. 2.像public成员一 ...
- JDK5特性
静态导入(了解) JDK 1.5 增加的静态导入语法用于导入类的某个静态属性或方法.使用静态导入可以简化程序对类静态属性和方法的调用. 语法: import static 包名.类名.静态属性|静态方 ...
- 安装pywin32时,出现找不到python27注册信息的解决办法
1. 检查一下注册表是否存在python其它版本的信息 方法: 1)在命令行中输入regedit打开注册表 2)在HKEY_CURRENT_USER\Software中找一下是否存在python注册信 ...
- react中循环节点的方式以及图片引用的方式
import React from 'react' import img from '../public/img/001.jpg' // 此时img是一个变量,在下面直接使用该变量即可引入该图片 cl ...
- Automake使用(高级)
工程地址 automake语言国际化 最初工程目录结构 $ ls -l total 16 drwxrwxr-x. 2 fedora fedora 4096 May 10 10:38 build-aux ...
- Unite 2017 | Unity引擎发展四大方向
Unite 2017 Shanghai已落幕,今天为大家分享本次大会备受关注的Keynote主题演讲.本次大会Keynote主题演讲聚焦了Unity全球领导团队,包括Unity创始人David Hel ...
- [转]PBFT 算法详解
https://www.cnblogs.com/mafeng/p/8405375.html
- ajax对象。同步与异步及ajax发送请求
ajax对象的属性.方法 属性 readyState: Ajax状态码 * 0:表示对象已建立,但未初始化,只是 new 成功获取了对象,但是未调用open方法 1:表示对象已初始化,但未发送,调用了 ...
- PJzhang:python快速搭建局域网文件共享服务器
猫宁!!! 参考链接:https://www.cnblogs.com/nopnog/p/8116848.html https://www.cnblogs.com/yili16438/p/d320932 ...