水壶-[Kruskal重构树] [解题报告]
###[水壶](http://oi.nks.edu.cn/zh/Problem/Details?cid=222&tid=H)
####本来从不写针对某题的题解,但因为自己实在是太蠢了,这道题也神TM的恶心,于是就写篇博客纪念一下
H水壶 |
---|
时间限制 : 50000 MS 空间限制 : 565536 KB 评测说明 : 2s,512m |
问题描述
\(JOI\)君所居住的IOI市以一年四季都十分炎热著称。
\(IOI\)市是一个被分成\(H*W\)块区域的长方形,每个区域都是建筑物、原野、墙壁之一。建筑物的区域有\(P\)个,编号为\(1...P\)。
$ JOI$君只能进入建筑物与原野,而且每次只能走到相邻的区域中,且不能移动到市外。
\(JOI\)君因为各种各样的事情,必须在各个建筑物之间往返。虽然建筑物中的冷气设备非常好,但原野上的日光十分强烈,因此在原野上每走过一个区域都需要\(1\)单位的水。此外,原野上没有诸如自动售货机、饮水处之类的东西,因此\(IOI\)市的市民一般都携带水壶出行。大小为\(x\)的水壶最多可以装\(x\)单位的水,建筑物里有自来水可以将水壶装满。
由于携带大水壶是一件很困难的事情,因此\(JOI\)君决定携带尽量小的水壶移动。因此,为了随时能在建筑物之间移动,请你帮他写一个程序来计算最少需要多大的水壶。
现在给出\(IOI\)市的地图和\(Q\)个询问,第i个询问\((1<=i<=Q)\)为“在建筑物\(S_i\)和\(T_i\)之间移动,最小需要多大的水壶?”,请你对于每个询问输出对应的答案。
输入格式
第一行四个空格分隔的整数\(H,W,P,Q\),表示\(IOI\)市被分成了纵\(H*W\)块区域,有\(P\)个建筑物,\(Q\)次询问。
接下来\(H\)行,第\(i\)行\((1<=i<=H)\)有一个长度为\(W\)的字符串,每个字符都是’.’或’#’之一,\(’.’\)表示这个位置是建筑物或原野,’#’表示这个位置是墙壁。
接下来\(P\)行描述\(IOI\)市每个建筑物的位置,第\(i\)行\((1<=i<=P)\)有两个空格分隔的整数\(Ai\)和\(Bi\),表示第i个建筑物的位置在第\(A_i\)行第\(B_i\)列。保证这个位置在地图中是’.’
接下来\(Q\)行,第\(i\)行\((1<=i<=Q)\)有两个空格分隔的整数\(S_i\)和\(T_i\),表示第\(i\)个询问为“在建筑物\(Si\)和\(Ti\)之间移动,最小需要多大的水壶?”
输出格式
输出\(Q\)行,第\(i\)行\((1<=i<=Q)\)一个整数,表示在建筑物\(S_i\)和\(T_i\)之间移动最小需要多大的水壶。 如果无法到达,输出\(-1\)。此外,如果不需要经过原野就能到达,输出\(0\)。
样例输入
5 5 4 4
.....
..##.
.#...
..#..
.....
1 1
4 2
3 3
2 5
1 2
2 4
1 3
3 4
样例输出
3
4
4
2
提示
\(1<=H<=2000\)
\(1<=W<=2000\)
\(2<=P<=2*10^5\)
\(1<=Q<=2*10^5\)
\(1<=A_i<=H(1<=i<=P)\)
\(1<=B_i<=W(1<=i<=P)\)
\((A_i,B_i)≠(A_j,B_j)(1<=i<j<=P)\)
\(1<=S_i<T_i<=P(1<=i<=Q)\)
题解
很显然这道题的询问类似于\(NOIP2015\)运输计划(不知道是不是这年的题啊),我们可以轻松愉快的使用\(Kruskal\)重构树或者很棒很棒的直接倍增记录;
但是这个方格图就很恶心,我们需要自己建一个仅有我们所需建筑的点和链接他们的边的图出来,这可咋整?
这就是这道题较为恶心的地方,我们可以对每一块染色,每当我们到达一个已被其他颜色染色的合法区域,把这条边就可以加入我们的存边数组,不知道开多大,就用\(Vector\)来存储;
但其实这并不是恶心我的地方\(,,,\),恶心的是\(LCA\)居然写错,\(WA,MLE\)到天上了简直惨死,下次再在写\(Kruskal\)重构树求\(LCA\)时把\(log_[tot]\)开成\(log_[n]\)就原地自爆,更别提写LCA写成Del=dep[x]-dep[x];
\(code:\)
#include<cstdio>
#include<algorithm>
#include<ctype.h>
#include<vector>
#include<queue>
#include<cstring>
#define lowbit(x) (x&-x)
#define ll long long
#define ld double
#include<map>
#include<stdlib.h>
#include<ctime>
#define mod 19260817
using namespace std;
char buf[1<<20],*p1,*p2;
inline char gc()
{
// return getchar();
return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin))==p1?0:*p1++;
}
template<typename T>
inline void read(T &x)
{
char tt;
bool flag=0;
while(!isdigit(tt=gc())&&tt!='-');
tt=='-'?(flag=1,x=0):(x=tt-'0');
while(isdigit(tt=gc())) x=x*10+tt-'0';
if(flag) x=-x;
}
const int maxn=200002;
struct node{
int x,y,len;
inline node(int a=0,int b=0,int c=0)
{x=a,y=b;len=c;}
inline bool operator<(node a)const
{return len>a.len;}
};
int n,m,p,que,tot;
int w[maxn<<1],fa[maxn<<1][20],dd[maxn<<1],dep[maxn<<1];
int log_[maxn<<1];
int book[2002][2002],dis[2002][2002];
int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};
char G[2002][2002];
vector<int>g[maxn<<1];
vector<node>a;
queue<node>q;
int getfa(int x){
return x==dd[x]?x:dd[x]=getfa(dd[x]);
}
void bfs()
{
for(int i=1;i<=p;i++)
{
int x,y;
read(x),read(y);
q.push(node(x,y));
book[x][y]=i;
}
while(!q.empty())
{
int id,x,y;
x=q.front().x,y=q.front().y;
id=book[x][y];q.pop();
for(int i=0;i<4;i++)
{
int tx=x+dx[i],ty=y+dy[i];
if(tx<=0||tx>n||ty<=0||ty>m||G[tx][ty]=='#'||book[tx][ty]==id) continue;
if(book[tx][ty])
a.push_back(node(id,book[tx][ty],dis[x][y]+dis[tx][ty]));
else
{
q.push(node(tx,ty));
dis[tx][ty]=dis[x][y]+1;
book[tx][ty]=id;
}
}
}
}
void dfs(int x,int pre)
{
dep[x]=dep[pre]+1,fa[x][0]=pre;
for(int i=1;i<=log_[tot];i++)
if(fa[x][i-1]) fa[x][i]=fa[fa[x][i-1]][i-1];
else break;
for(int i=g[x].size()-1;i>=0;i--)
{
int p=g[x][i];
if(p==pre) continue;
dfs(p,x);
}
}
int query(int x,int y)
{
int fx=getfa(x),fy=getfa(y);
if(fx!=fy) return -1;
if(dep[x]<dep[y]) swap(x,y);
if(x==y) return 0;
int del=dep[x]-dep[y];
for(int i=log_[tot];i>=0;i--)
if(del>>i&1) x=fa[x][i];
if(x==y) return w[x];
for(int i=log_[n];i>=0;i--)
if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
return w[fa[x][0]];
}
int main()
{
read(n),read(m),read(p),read(que);
for(int i=1;i<=n;i++,gc())
for(int j=1;j<=m;j++)
G[i][j]=gc();tot=p;
bfs();
sort(a.begin(),a.end());log_[0]=-1;
for(int i=1;i<=p<<1;i++) dd[i]=i,log_[i]=log_[i>>1]+1;
for(int i=a.size()-1;i>=0;i--)
{
int fx=getfa(a[i].x),fy=getfa(a[i].y),len=a[i].len;;
if(fx==fy) continue;
dd[fx]=dd[fy]=++tot;
g[tot].push_back(fx);
g[tot].push_back(fy);
w[tot]=len;
}
for(int i=tot;i>=1;i--) if(!dep[i]) dfs(i,0);
while(que--)
{
int x,y;
read(x),read(y);
printf("%d\n",query(x,y));
}
}
找个时间填\(Kruskal\)重构树的坑\(ORZ,ORZ\)
水壶-[Kruskal重构树] [解题报告]的更多相关文章
- [jzoj 5926] [NOIP2018模拟10.25] naive 的图 解题报告(kruskal重构树+二维数点)
题目链接: https://jzoj.net/senior/#main/show/5926 题目: 题解: 显然最小的最大路径在最小生成树上(最小生成树=最小瓶颈生成树) 于是我们建出kruskal重 ...
- [luogu P4197] Peaks 解题报告(在线:kruskal重构树+主席树 离线:主席树+线段树合并)
题目链接: https://www.luogu.org/problemnew/show/P4197 题目: 在Bytemountains有N座山峰,每座山峰有他的高度$h_i$.有些山峰之间有双向道路 ...
- BZOJ 4242: 水壶(Kruskal重构树 + Bfs)
题意 一块 \(h ∗ w\) 的区域,存在障碍.空地.\(n\) 个建筑,从一个建筑到另一个建筑的花费为:路径上最长的连续空地的长度. \(q\) 次询问:从建筑 \(s_i\) 到 \(t_i\) ...
- NOI2018归程(Kruskal重构树)
题目描述 本题的故事发生在魔力之都,在这里我们将为你介绍一些必要的设定. 魔力之都可以抽象成一个 n 个节点.m 条边的无向连通图(节点的编号从 1 至 n). 我们依次用 l,a 描述一条边的长度. ...
- BZOJ 5415: [Noi2018]归程(kruskal重构树)
解题思路 \(NOI2018\)的\(Day1\) \(T1\),当时打网络赛的时候不会做.学了一下\(kruskal\)重构树后发现问题迎刃而解了.根据\(kruskal\)的性质,如果要找从\(u ...
- AT4144-[ARC098D]Donation【Kruskal重构树,dp】
正题 题目链接:https://www.luogu.com.cn/problem/AT4144 题目大意 \(n\)个点\(m\)条边的一张无向联通图,每个点有两个值\(a_i,b_i\).表示经过该 ...
- [bzoj 3732] Network (Kruskal重构树)
kruskal重构树 Description 给你N个点的无向图 (1 <= N <= 15,000),记为:1-N. 图中有M条边 (1 <= M <= 30,000) ,第 ...
- 【BZOJ 3732】 Network Kruskal重构树+倍增LCA
Kruskal重构树裸题, Sunshine互测的A题就是Kruskal重构树,我通过互测了解到了这个神奇的东西... 理解起来应该没什么难度吧,但是我的Peaks连WA,,, 省选估计要滚粗了TwT ...
- 【BZOJ-3545&3551】Peaks&加强版 Kruskal重构树 + 主席树 + DFS序 + 倍增
3545: [ONTAK2010]Peaks Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1202 Solved: 321[Submit][Sta ...
随机推荐
- Android - ANR小结
Application Not Responding 在Android上,如果你的应用程序有一段时间响应不够灵敏,系统会向用户显示一个对话框,这个对话框称作应用程序无响应(ANR:Applicatio ...
- js中的json的小例子
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xht ...
- Linux常用基本命令(more)
more命令 作用:相比cat一次性显示文件内容,more用于分页显示内容,less比more更强大,大多数的参数类似 more [option] [file] -num : 每页显示num行 +nu ...
- Codeforces445B(SummerTrainingDay06-N 并查集)
B. DZY Loves Chemistry time limit per test:1 second memory limit per test:256 megabytes input:standa ...
- js-ES6学习笔记-Class(5)
1.原生构造函数会忽略apply方法传入的this,也就是说,原生构造函数的this无法绑定,导致拿不到内部属性.比如,Array构造函数有一个内部属性[[DefineOwnProperty]],用来 ...
- ONLYOFFICE连接数20个限制的由来
搜onlyoffice document server的github上的issue,会得到这2个地址https://github.com/ONLYOFFICE/DocumentServer/issue ...
- Win10 开启便签快捷键
前提: Win10系统 方法: 开启便签的快捷键:windows+W 这样就可以打开便签,使用起来非常方便
- Android开发工具Android Studio、Android SDK和Genymotion完全配置
所谓“工欲善其事,必先利其器”.Android Studio 是谷歌推出一个Android集成开发工具,基于IntelliJ IDEA. 类似 Eclipse ADT,Android Studio 提 ...
- Laravel安装教程
1.Call to undefined function Illuminate\Encryption\openssl_cipher_iv_length() 报这个错是因为Apache/bin目录下 l ...
- python 遇到的一些坑
lst = [1, 2, 4] print lst.__iter__().next() # 打印出来的是 1 print lst.__iter__().next() # 打印出来的是 1 # 调用__ ...