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 的小格子. 有 ...
随机推荐
- 《SpringBoot揭秘 快速构建微服务体系》读后感(一)
SpringIOC IOC有两种方式:一种是DI,另一种是DL,即Dependency Lookup(依赖查找).前者是当前软件实体被动接受其依赖的其他组件被IoC容器注入,而后者则是当前软件实体主动 ...
- C#中异步及winform中界面假死
c#中可以用BeginInvoke去启动异步调用,但是有两个BeginInvoke一个是controller的BeginInvoke还有一个是委托的BeginInvoke. 主要区别是controll ...
- Linux+ant+jmeter+Jenkins接口持续集成自动化框架搭建
Linux下安装ant并配置环境变量 1.从http://ant.apache.org 上下载tar.gz版ant 2.复制到/usr下 3.tar -vxzf apache-ant-1.10.1-b ...
- 3dmax tcb控制器
https://wenku.baidu.com/video/course/v/3a0e059d884c4d0b03bf85441b87311b 7.48开始 tcb控制器比较适合产生平滑动画 张力Te ...
- C#中的结构体要使用new来实例化吗?
声明结构的默认(无参数)构造函数是错误的.总是提供默认构造函数以将结构成员初始化为它们的默认值.在结构中初始化实例字段也是错误的. 如果使用 new 运算符创建结构对象,则会创建该结构对象,并调用适当 ...
- Spark 中的 checkpoint
为了实现容错,需要做checkpoint.以Streaming为例,checkpoint中有两种数据: 1. Metadata checkpointing:用于恢复driver端出错的情况.其中包含: ...
- 洛谷P1313 计算系数
P1313 计算系数 题目描述 给定一个多项式(by+ax)^k,请求出多项式展开后x^n*y^m 项的系数. 输入输出格式 输入格式: 输入文件名为factor.in. 共一行,包含5 个整数,分别 ...
- SpringMVC重定向传递参数
在SpringMVC的一个controller中要把参数传到页面,只要配置视图解析器,把参数添加到Model中,在页面用el表达式就可以取到.但是,这样使用的是forward方式,浏览器的地址栏是不变 ...
- Maven对坐标的管理 自动导入传递依赖 坐标和传递依赖分级显示
- Linux上传下载工具 lrzsz