The 2021 ICPC Asia Regionals Online Contest (II) J Leaking Roof (拓扑排序)

J Leaking Roof

Grandpa Are lives in an old house. Now it is the heavy rain that occurs only once in a hundred years, but the roof of Grandpa Are’s house leaks. His roof can be viewed as a n×n grid, and each square has a height. Denote the height of the square with coordinate (i,j) by hi,j meters. Now the rainfall is m millimeters, meaning that the incoming rain on every square is m millimeters.

Since the roof is not flat, the water flows, and the water on a square can only flow to an adjacent square with a strictly smaller height. Two squares are adjacent when they share a common edge. Also, since the water level is subtle compared with the difference in heights of the squares, water will NOT flow to adjacent squares with the same height due to surface tension. Furthermore, the water equally divides among all possible directions. Besides, the roof leaks. To be specific, if a square has a height of 0, it leaks.

Grandpa Are wants to know how much water flows to each leaking square after a long time. The water flows to a square includes the one from the incoming rain and the one from the adjacent squares. He asks you to calculate for him.

输入描述

The first line contains two integers n and m.

The next n lines contains n integers in each line. The i-th line contains integer hi,1,…,hi,n, separated by a space, meaning the height of the squares in the i-th row. There is a space in the end of each line, and there is an eoln in the end of the n-th line.

It is guaranteed that 1≤n≤500 and 0≤m,hi,j≤10000.

输出描述

There are n lines in the output, and each line contains n real numbers. The i-th line contains ai,1,…,ai,n, separated by a space, meaning the height of water flows to the corresponding square at last, or 0 if the square is not leaking.

Your answer will be considered correct if and only if the absolute or relative error of your answer to the correct answer is less than or equal to 1e-6 . Also, there is a space in the end of each line, and there is an eoln in the end of the n-th line.

样例1

输入

3 1
0 1 2
1 2 3
2 3 4

输出

9.000000 0 0 
0 0 0 
0 0 0 

样例2

输入

3 1
0 1 0
1 1 1
0 1 0

输出

2.000000 0 2.000000 
0 0 0 
2.000000 0 2.000000 

题意

给一个n*n的矩阵h,hij代表某处的高度,水会从高处往低处流,两处高度相等或低往高都不会流。每个点的降雨量均为m,问最后每个点的水量是多少(高度不为0则输出0,高度为0则输出水量)。

思路

属实签到题,读完题队友就说拓扑排序,但写完没调出来。我上机写完一直过不了,现在才发现,一开始计算入度忘记check导致越界了。重点主要在于是要想办法从高到低来对每个点进行判断,做法包括但不限于拓扑排序。

代码

#include<bits/stdc++.h>
using namespace std;

const int N=505;

int n,m;
int h[N][N];
int in[N][N];
int out[N][N];
double ans[N][N];
int d[2][4]={1,0,-1,0,0,1,0,-1};

bool check(int x,int y) {
	if(x>=1&&x<=n&&y>=1&&y<=n) return 1;
	else return 0;
}

void tsort() {
	queue<pair<int,int>> q;
	for(int i=1;i<=n;i++)
	    for(int j=1;j<=n;j++)
	        if(!in[i][j]) q.push({i,j});
	while(q.size()) {
		auto t=q.front();
		q.pop();
		int x=t.first,y=t.second;
		for(int i=0;i<4;i++) {
			int xx=x+d[0][i],yy=y+d[1][i];
			if(check(xx,yy)&&h[x][y]>h[xx][yy]) {
				ans[xx][yy]+=ans[x][y]/out[x][y];
				in[xx][yy]--;
				if(!in[xx][yy]) q.push({xx,yy});
			}
		}
	}
} 

int main() {
	cin>>n>>m;
	for(int i=1;i<=n;i++) 
	    for(int j=1;j<=n;j++) {
	    	cin>>h[i][j];
	    	ans[i][j]=m;
		}
	for(int i=1;i<=n;i++)
	    for(int j=1;j<=n;j++)
            for(int k=0;k<4;k++) {
            	int x=i+d[0][k],y=j+d[1][k];
            	if(check(x,y)) {
            		if(h[i][j]<h[x][y]) in[i][j]++;
            		if(h[i][j]>h[x][y]) out[i][j]++;
				}
			}
	tsort();
	for(int i=1;i<=n;i++) {
		for(int j=1;j<=n;j++)
	        if(!h[i][j]) printf("%.8f ",ans[i][j]);
	        else printf("0 ");
	    printf("\n");
	}
	return 0;
} 

原题链接

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值