题意

一块 \(h ∗ w\) 的区域,存在障碍、空地、\(n\) 个建筑,从一个建筑到另一个建筑的花费为:路径上最长的连续空地的长度。

\(q\) 次询问:从建筑 \(s_i\) 到 \(t_i\) 的最小花费。

\(h, w \le 2 \times 10^3 ,n, q \le 2 \times 10^5\)

题解

对于任意两个建筑把它们之间的只走空地的最短路长度作为权值,然后做最小生成树。

如果搞出了最小生成树,那么就只需在 \(kruskal\) 重构树上求 \(LCA\) 就行了,因为 \(LCA\) 的权值是路上所有边的最大权值。

如果不会可以参考 「NOI2018」归程(Dijkstra + Kruskal重构树 + 倍增) 这题。

然而边数达到 \(O(n^2)\) ,暴力求边需要 \(O(n*h*w)\) 。

把所有建筑一起作为源点,跑 \(bfs\) ,可以得到离每个位置最近的建筑及距离。

然后,如果两个相邻位置的最近建筑不同,那么就将这对建筑连边,边数就降成 \(O(h * w)\) 的。

对于一个点如果存在多个最近的点,我们其实只需要把所有点连向第一个 \(bfs\) 到这个的点就行了,可以证明这是对的。(能自己画图理解)

所以最后复杂度就是 \(O(h * w \log (h * w) + q \log n)\)

总结

这种路径上 最大 / 最小 作为权值的题,常常可以考虑 \(kruskal\) 重构树来做。

平面上连边常常可以找特殊点来减少边数。

代码

/**************************************************************
Problem: 4242
User: DOFY
Language: C++
Result: Accepted
Time:32156 ms
Memory:271236 kb
****************************************************************/ #include <bits/stdc++.h> #define For(i, l, r) for(register int i = (l), i##end = (int)(r); i <= i##end; ++i)
#define Fordown(i, r, l) for(register int i = (r), i##end = (int)(l); i >= i##end; --i)
#define Set(a, v) memset(a, v, sizeof(a))
#define Cpy(a, b) memcpy(a, b, sizeof(a))
#define debug(x) cout << #x << ": " << (x) << endl
#define DEBUG(...) fprintf(stderr, __VA_ARGS__)
#define fir first
#define sec second
#define mp make_pair using namespace std; typedef pair<int, int> PII; template<typename T> inline bool chkmin(T &a, T b) {return b < a ? a = b, 1 : 0;}
template<typename T> inline bool chkmax(T &a, T b) {return b > a ? a = b, 1 : 0;} inline int read() {
int x(0), sgn(1); char ch(getchar());
for (; !isdigit(ch); ch = getchar()) if (ch == '-') sgn = -1;
for (; isdigit(ch); ch = getchar()) x = (x * 10) + (ch ^ 48);
return x * sgn;
} void File() {
#ifdef zjp_shadow
freopen ("4242.in", "r", stdin);
freopen ("4242.out", "w", stdout);
#endif
} const int Maxn = 2010, N = 4e5 + 1e3; bool G[Maxn][Maxn]; char str[Maxn]; queue<PII> Q; int id[Maxn][Maxn], dis[Maxn][Maxn]; struct Edge {
int u, v, w;
} lt[Maxn * Maxn * 4]; struct Cmp {
inline bool operator () (const Edge &lhs, const Edge &rhs) const {
return lhs.w < rhs.w;
}
}; int fa[N];
int find(int x) {
return x == fa[x] ? x : fa[x] = find(fa[x]);
} int h, w, p, q; const int dir[4][2] = { {0, -1}, {0, 1}, {1, 0}, {-1, 0} }; int dep[N], val[N], anc[N][21], Log[N], Size; int Get_Dep(int u) {
if (!u || dep[u]) return dep[u];
return dep[u] = Get_Dep(anc[u][0]) + 1;
} int tot = 0;
void Build_Kruskal() {
For (i, 1, Size = p) fa[i] = i;
sort(lt + 1, lt + tot + 1, Cmp());
For (i, 1, tot) {
int u = find(lt[i].u), v = find(lt[i].v), w = lt[i].w;
if (u == v) continue ;
val[++ Size] = w;
fa[Size] =
anc[u][0] = fa[u] =
anc[v][0] = fa[v] = Size;
}
For (i, 1, Size) {
if (i > 1) Log[i] = Log[i >> 1] + 1;
dep[i] = Get_Dep(i);
}
For (j, 1, Log[Size]) For (i, 1, Size)
anc[i][j] = anc[anc[i][j - 1]][j - 1];
} inline int Calc(int u, int v) {
if (find(u) != find(v)) return -1;
if (dep[u] < dep[v]) swap(u, v);
int gap = dep[u] - dep[v];
For (i, 0, Log[gap]) if (gap >> i & 1) u = anc[u][i];
if (u == v) return val[u];
Fordown (i, Log[dep[u]], 0)
if (anc[u][i] != anc[v][i]) u = anc[u][i], v = anc[v][i];
return val[anc[u][0]];
} int main () { File(); h = read(), w = read(), p = read(), q = read(); For (i, 1, h) {
scanf ("%s", str + 1);
For (j, 1, w) G[i][j] = str[j] == '.';
} Set(dis, -1);
For (i, 1, p) {
int x = read(), y = read();
Q.push(mp(x, y)); id[x][y] = i; dis[x][y] = 0;
} while (!Q.empty()) {
PII u = Q.front(); Q.pop();
For (i, 0, 3) {
register int x = u.fir + dir[i][0], y = u.sec + dir[i][1];
if (!G[x][y]) continue ;
if (id[x][y]) {
if (id[x][y] != id[u.fir][u.sec])
lt[++ tot] = (Edge){id[x][y], id[u.fir][u.sec], dis[x][y] + dis[u.fir][u.sec]};
} else {
dis[x][y] = dis[u.fir][u.sec] + 1;
id[x][y] = id[u.fir][u.sec]; Q.push(mp(x, y));
}
}
} Build_Kruskal(); For (i, 1, q)
printf ("%d\n", Calc(read(), read())); return 0; }

BZOJ 4242: 水壶(Kruskal重构树 + Bfs)的更多相关文章

  1. BZOJ.4793.[CERC2016]Hangar Hurdles(Kruskal重构树 BFS)

    题目链接 \(Description\) 有一个\(n\times n\)的正方形网格,上面有若干障碍点.\(q\)次询问,每次询问把一个正方形箱子从\((x1,y1)\)推到\((x2,y2)\) ...

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

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

  3. [bzoj 3732] Network (Kruskal重构树)

    kruskal重构树 Description 给你N个点的无向图 (1 <= N <= 15,000),记为:1-N. 图中有M条边 (1 <= M <= 30,000) ,第 ...

  4. BZOJ 4242: 水壶 Kruskal+BFS

    4242: 水壶 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 427  Solved: 112[Submit][Status][Discuss] D ...

  5. BZOJ 3732: Network Kruskal 重构树

    模板题,练练手~ Code: #include <cstdio> #include <algorithm> #define N 80000 #define setIO(s) f ...

  6. 【BZOJ 3732】 Network Kruskal重构树+倍增LCA

    Kruskal重构树裸题, Sunshine互测的A题就是Kruskal重构树,我通过互测了解到了这个神奇的东西... 理解起来应该没什么难度吧,但是我的Peaks连WA,,, 省选估计要滚粗了TwT ...

  7. BZOJ 3551: [ONTAK2010]Peaks加强版 [Kruskal重构树 dfs序 主席树]

    3551: [ONTAK2010]Peaks加强版 题意:带权图,多组询问与一个点通过边权\(\le lim\)的边连通的点中点权k大值,强制在线 PoPoQQQ大爷题解传送门 说一下感受: 容易发现 ...

  8. bzoj 3551 kruskal重构树dfs序上的主席树

    强制在线 kruskal重构树,每两点间的最大边权即为其lca的点权. 倍增找,dfs序对应区间搞主席树 #include<cstdio> #include<cstring> ...

  9. 【BZOJ】3732: Network【Kruskal重构树】

    3732: Network Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2812  Solved: 1363[Submit][Status][Dis ...

随机推荐

  1. Django之在Python中调用Django环境

    Django之在Python中调用Django环境 新建一个py文件,在其中写下如下代码: import os if __name__ == '__main__': os.environ.setdef ...

  2. 什么是arp协议?

    转自:https://blog.csdn.net/tigerjibo/article/details/7351992 ARP (Address Resolution Protocol) 是个地址解析协 ...

  3. C#设计模式之5:简单工厂和工厂方法模式

    工厂模式包含三种,简单工厂模式,工厂方法模式,抽象工厂模式.这三种都是解决了一个问题,那就是对象的创建问题.他们的职责就是将对象的创建和对象的使用分离开来. 当我们创建对象的时候,总是会new一个对象 ...

  4. 查找文献的BibTex

    BibTex可以通过Google Scholar来查找. 注意,默认情况下,Google scholar 关闭了显示BibTex链接. 打开Google Scholar 选择右上角菜单按钮 选择set ...

  5. Some beautiful Progress Bars in WPF

    1.Better WPF Circular Progress Bar 2.Bending the WPF ProgressBar 3.A CIRCULAR PROGRESSBAR STYLE USIN ...

  6. python爬虫之线程池和进程池

    一.需求 最近准备爬取某电商网站的数据,先不考虑代理.分布式,先说效率问题(当然你要是请求的太快就会被封掉,亲测,400个请求过去,服务器直接拒绝连接,心碎),步入正题.一般情况下小白的我们第一个想到 ...

  7. python之路--管道, 事件, 信号量, 进程池

    一 . 管道 (了解) from multiprocessing import Process, Pipe def f1(conn): # 管道的recv 里面不用写数字 from_main_proc ...

  8. spring boot session error

    Error starting ApplicationContext. To display the conditions report re-run your application with 'de ...

  9. docker学习笔记一

    知识点: 1)docker简介 2)docker安装,仓库配置 3)docker仓库镜像拉取,导出,导入,删除 4)docker容器操作,容器的创建,删除,运行,停止,日志查看等. 5)  docke ...

  10. Plugin/Preset files are not allowed to export objects,webpack报错/babel报错的解决方法

    1.为什么会报错 ? 这里抱着错误是因为 babel 的版本冲突. 多是因为你的 babel 依赖包不兼容. 可以查看你的 package.json 的依赖列表 即有 babel 7.0 版本的( @ ...