问题描述

秋之国首都下了一场暴雨,由于秋之国地势高低起伏,不少地方出现了积水。

秋之国的首都可以看成一个 n 行 m 列的矩阵,第 i 行第 j 列的位置高度为 ai,j,首都以外的地方的高度可以都看成 0。我们假设下的雨无限多,暴雨时,水位线超过了所有位置的高度。暴雨结束后,如果有雨水的高度超过的四相邻(上下左右)的位置的高度,水就会流过去,如果流到了首都外,水会消失。你需要求出最后每个位置的积水高度。

输入格式

第一行两个非负整数 n,m。

接下来 n 行,每行 m 个整数,表示 ai,j。

输出格式

输出 n 行,每行 m 个整数,表示每个位置的积水高度。

样例输入

3 3

4 4 0

2 1 3

3 3 -1

样例输出

0 0 0

0 1 0

0 0 1

解析

假如一个方格内的水能够留到外面去,这个方格中就不会有积水。水往低处流,将每个方格视为一个点,往四周比自己低的点连边,边权为两个高度的最大值。将城外单独作为一点,往所有在边界的点连边。由木桶原理,一个水池的高度一定由边缘高度最小的点决定。那么,一个点的高度会由到边界外的路径中经过的边权最大值最小的路径决定,记这个最大值为b。这样的路径一定是图的最小生成树上到城外点的路径。由此,我们得到如下算法:

连边构图完成后,将图的最小生成树求出来,在树上求城外点到每个点的路径上的最大值b,最后的答案即为\(b-a[i][j]\)。

代码

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define N 302
using namespace std;
struct node{
int u,v,w;
}e[N*N*4];
int p[4]={1,-1,0,0},q[4]={0,0,1,-1};
int head[N*N],ver[N*N*4],nxt[N*N*4],edge[N*N*4],l,tot;
int n,m,i,j,k,a[N][N],id[N][N],cnt,fa[N*N],dis[N*N];
bool in(int x,int y)
{
return x<=n&&x>=1&&y<=m&&y>=1;
}
void insert(int x,int y,int z)
{
l++;
ver[l]=y;
edge[l]=z;
nxt[l]=head[x];
head[x]=l;
}
int my_comp(const node &x,const node &y)
{
return x.w<y.w;
}
int find(int x)
{
if(fa[x]!=x) fa[x]=find(fa[x]);
return fa[x];
}
void Kruscal()
{
sort(e+1,e+tot+1,my_comp);
for(i=1;i<=n*m;i++) fa[i]=i;
int cnt=n*m+1;
for(int i=1;i<=tot;i++){
if(cnt==1) break;
int f1=find(e[i].u),f2=find(e[i].v);
if(f1!=f2){
insert(e[i].u,e[i].v,e[i].w);
insert(e[i].v,e[i].u,e[i].w);
fa[f1]=f2;
cnt--;
}
}
}
void dfs(int x,int pre)
{
for(int i=head[x];i!=-1;i=nxt[i]){
int y=ver[i];
if(y!=pre){
dis[y]=max(dis[x],edge[i]);
dfs(y,x);
}
}
}
int main()
{
freopen("water.in","r",stdin);
freopen("water.out","w",stdout);
cin>>n>>m;
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
cin>>a[i][j];
id[i][j]=++cnt;
}
}
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
if(i==1||i==n||j==1||j==m) e[++tot]=(node){0,id[i][j],max(0,a[i][j])};
for(k=0;k<4;k++){
int x=i+p[k],y=j+q[k];
if(in(x,y)&&a[x][y]<=a[i][j]) e[++tot]=(node){id[x][y],id[i][j],max(a[x][y],a[i][j])};
}
}
}
memset(head,-1,sizeof(head));
Kruscal();
dfs(0,0);
cnt=0;
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
cnt++;
cout<<dis[cnt]-a[i][j]<<' ';
}
cout<<endl;
}
fclose(stdin);
fclose(stdout);
return 0;
}

Test 6.24 T3 水题的更多相关文章

  1. cdoj 24 8球胜负(eight) 水题

    8球胜负(eight) Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/show/24 ...

  2. [poj2247] Humble Numbers (DP水题)

    DP 水题 Description A number whose only prime factors are 2,3,5 or 7 is called a humble number. The se ...

  3. gdutcode 1195: 相信我这是水题 GDUT中有个风云人物pigofzhou,是冰点奇迹队的主代码手,

    1195: 相信我这是水题 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 821  Solved: 219 Description GDUT中有个风云人 ...

  4. hdu 2041:超级楼梯(水题,递归)

    超级楼梯 Time Limit: / MS (Java/Others) Memory Limit: / K (Java/Others) Total Submission(s): Accepted Su ...

  5. Educational Codeforces Round 7 B. The Time 水题

    B. The Time 题目连接: http://www.codeforces.com/contest/622/problem/B Description You are given the curr ...

  6. CYJian的水题大赛

    实在没忍住就去打比赛了然后一耗就是一天 最后Rank19还是挺好的(要不是乐多赛不然炸飞),这是唯一一套在Luogu上号称水题大赛的而实际上真的是水题大赛的比赛 好了我们开始看题 T1 八百标兵奔北坡 ...

  7. 【转】POJ百道水题列表

    以下是poj百道水题,新手可以考虑从这里刷起 搜索1002 Fire Net1004 Anagrams by Stack1005 Jugs1008 Gnome Tetravex1091 Knight ...

  8. HDU - 1716 排列2 水题

    排列2 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submis ...

  9. HDU--Elevator(水题)

    Elevator nid=24#time"> Time Limit: 1000ms   Memory limit: 32768K  有疑问?点这里^_^ 题目描写叙述 The high ...

随机推荐

  1. percona-toolkit 工具介绍

    percona-toolkit 工具介绍 percona-toolkit 是一组高级命令行工具的集合,用来执行各种通过手工执行非常复杂和麻烦的mysql和系统任务.这些任务包括: 检查master和s ...

  2. Android流媒体开发之路三:基于NDK开发Android平台RTSP播放器

    基于NDK开发Android平台RTSP播放器 最近做了不少android端的开发,有推流.播放.直播.对讲等各种应用,做了RTMP.RTSP.HTTP-FLV.自定义等各种协议,还是有不少收获和心得 ...

  3. Catalan numbers

    w https://en.wikipedia.org/wiki/Catalan_number 路径规划

  4. AtomicReference 源码分析

    AtomicReference AtomicReference 能解决什么问题?什么时候使用 AtomicReference? 1)AtomicReference 可以原子更新引用对象. 2)comp ...

  5. (转)grep命令

    1.作用Linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来.grep全称是Global Regular Expression Print,表示全局 ...

  6. flex embed 使用

    Flex 软件中经常需要使用一些外部的资源,如图片.声音.SWF或字体,虽然你也可以在软件运行的时候引入和载入,但是也可能经常需要直接将这些资源编译(Compile)到软件中,也就是直接嵌入资源(Em ...

  7. Linux QQ全新回归

    福音! 2019年10月24日,腾讯官方发布QQ Linux 2.0.0 Beta版本,告示着Linux QQ的回归. 2008年,腾讯曾推出QQ for Linux,但2009年之后就再没有更新过, ...

  8. java 集合基础(适用单线程)

    1.集合树状: Collection ├List │├LinkedList │├ArrayList │└Vector │ └Stack └Set │├HashSet │├TreeSet │├Linke ...

  9. dataTables使用的详细说明整理

    本文共三个部分:官网|基本使用|遇到的问题 一.官方网站:http://www.datatables.club/ 二.基本使用: 1.dataTables的引入及初始化 <!--第一步:引入Ja ...

  10. ceph部署-集群建立

    一.配置storage集群1.建立集群管理目录(管理配置文件,密钥)mkdir ceph-clustercd ceph-cluster/ 2.创建一个新集群(需要先将主机名加入/etc/hosts 必 ...