问题描述

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

秋之国的首都可以看成一个 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. leetcode-mid-Linked list-2 Add Two Numbers

    mycode 87.22% # Definition for singly-linked list. # class ListNode(object): # def __init__(self, x) ...

  2. easyui表格适应bootstrap

    .panel1 { overflow: hidden; text-align: left; margin:; border:; -moz-border-radius: 0 0 0 0; -webkit ...

  3. kafka 生产者发送消息

    KafkaProducer 创建一个 KafkaThread 来运行 Sender.run 方法. 1. 发送消息的入口在 KafkaProducer#doSend 中,但其实是把消息加入到 batc ...

  4. 阶段1 语言基础+高级_1-3-Java语言高级_04-集合_07 Collections工具类_1_Collections集合工具类的方法

    这是一个个的添加的方式 参数是个可变的元素.可以传递任意多的元素 shuffle打乱集合元素顺序

  5. Week 12 - 673.Number of Longest Increasing Subsequence

    Week 12 - 673.Number of Longest Increasing Subsequence Given an unsorted array of integers, find the ...

  6. delphi自定义事件处理

    http://www.cnblogs.com/ywangzi/archive/2012/09/06/2673414.html delphi自定义事件处理   为什么我们点击按钮,就会执行按钮的oncl ...

  7. linux下mysql 5.7编写存储过程一直报错说Mysql server version for the right syntax

    首先看下可以正确执行的. 再来看保存时提示出错的 我唯一的区别就是在传参的类型那里有了变化,然而,报错如下 难道是我的类型不支持了吗,最后在一个无意识操作下,直接在类型里面限定长度. 可以运行啦.经过 ...

  8. display:table

    display:table的CSS声明能够让一个HTML元素和它的子节点像table元素一样.使用基于表格的CSS布局,使我们能够轻松定义一个单元格的边界.背景等样式,而不会产生因为使用了table那 ...

  9. HDU-1394 Minimum Inversion Number (逆序数,线段树或树状数组)

    The inversion number of a given number sequence a1, a2, ..., an is the number of pairs (ai, aj) that ...

  10. python 导入re模块语法及规则

    正则表达式是功能比较强大的模块,应用在很多地方,抓网页,数据分析,数据验证等,下面讲述python 导入re模块语法及规则. 1,re模块语法 re.match 从头开始匹配 re.search 匹配 ...