【luogu P5952】水箱(最小生成树)

水箱

题目链接:luogu P5952

题目大意

给你一个二维的矩阵,每个位置代表那个位置的水位,然后左右相连左右相连的位置都有一定高度的木板。
然后告诉你每个位置水位高度的上限,然后问你水位有多少种可能。

思路

不难发现一个特点,随着水位的增高,许多分开来(水位不同)的地方会合并。

那我们考虑“模拟”这个过程。
仔细想想就会发现这个过程你可以看做把每个水位看做点,然后木板看做边,那它就是要建一个最小生成树的过程。

那你就在合并的时候处理值即可。
具体一点的话就之前它本身的概率分别是 valx,valy(一开始全部都是 1),然后你记录它当前全部在一起的最低高度。(hx,hy

然后如果这次的高度是 w,那新合并之后的 val 就是 (valx+whx)(valy+why)

然后记得最后所有都合并完之后还有上升到限制高度的部分。

代码

#include<cstdio> #include<algorithm> #define ll long long #define mo 1000000007 using namespace std; int n, m, H, x, fa[500001], h[500001], tot; struct node { int s, t, w; }w[1000001]; ll val[500001]; int get_bh(int x, int y) { return (x - 1) * m + y; } bool cmp(node x, node y) { return x.w < y.w; } int find(int now) { if (fa[now] == now) return now; return fa[now] = find(fa[now]); } int main() { scanf("%d %d %d", &n, &m, &H); for (int i = 1; i <= n * m; i++) { fa[i] = i; val[i] = 1; } for (int i = 1; i <= n; i++) for (int j = 1; j < m; j++) { scanf("%d", &x); w[++tot] = (node){get_bh(i, j), get_bh(i, j + 1), x}; } for (int i = 1; i < n; i++) for (int j = 1; j <= m; j++) { scanf("%d", &x); w[++tot] = (node){get_bh(i, j), get_bh(i + 1, j), x}; } sort(w + 1, w + tot + 1, cmp); for (int i = 1; i <= tot; i++) { int X = find(w[i].s), Y = find(w[i].t); if (X == Y) continue; fa[Y] = X; val[X] = (val[X] + w[i].w - h[X]) * (val[Y] + w[i].w - h[Y]) % mo; h[X] = w[i].w; } printf("%lld", (val[find(1)] + H - h[find(1)]) % mo); return 0; }

__EOF__

本文作者あおいSakura
本文链接https://www.cnblogs.com/Sakura-TJH/p/luogu_P5952.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   あおいSakura  阅读(37)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示