POJ2227bfs

区域有很多实心柱子;
俯视图矩形大小为n*m;
给出n*m个实心柱子的高度;
求最大的蓄水量。




思想:
1)构造环,联通的环来包围柱子;
2)从环上的点来扩展环,所以每次应该取出环上柱子高度最低的一个点;
3)扩展,扩展的点必须加入新环,这样就层层往里推进;


import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {
	public static void main(String[] args) {
		new Task().solve() ; 
	}
}

class Task {
	InputReader in = new InputReader(System.in) ;
	PrintWriter out = new PrintWriter(System.out) ;
	
	final int VIS = -1 ;
	int n , m ;
	int[][] high ; 
	int[][] dir = {{-1,0},{0,-1},{1,0},{0,1}} ;
	boolean can(int x , int y){
		return 0 <= x && x < n && 0 <= y && y < m ;
	}
	
	class Node implements Comparable<Node>{
		int x , y , h ;
		Node(int x , int y , int h){
			this.x = x ;
			this.y = y ;
			this.h = h ;
		}
		
		@Override
		public int compareTo(Node o) {
			return (h < o.h) ? -1 : ((h == o.h) ? 0 : 1);
		}
	}

	void solve() {
		m = in.nextInt() ;
		n = in.nextInt() ;
        high = new int[n][m] ;
        Queue<Node> q = new PriorityQueue<Node>() ;
        for(int i = 0 ; i < n ; i++){
        	for(int j = 0 ; j < m ; j++){
        		high[i][j] = in.nextInt() ;
        		if(i == 0 || i == n-1 || j == 0 || j == m-1){
        			q.offer(new Node(i, j, high[i][j])) ;
        			high[i][j] = VIS ;
        		}
        	}
        }
        
        int sum = 0 ;
        while(! q.isEmpty()){
        	Node u = q.poll() ;
            for(int i = 0 ; i < 4 ; i++){
            	int x = u.x + dir[i][0] ;
            	int y = u.y + dir[i][1] ;
            	if(can(x, y) && high[x][y] != VIS){
            		if(high[x][y] < u.h)  sum += u.h - high[x][y] ;
            		q.offer(new Node(x, y, Math.max(u.h , high[x][y])) ) ;
            		high[x][y] = VIS ;
            	}
            }
        }
        out.println(sum) ;
        out.flush() ; 
	}
}

class InputReader {
	public BufferedReader reader;
	public StringTokenizer tokenizer;

	public InputReader(InputStream stream) {
		reader = new BufferedReader(new InputStreamReader(stream), 32768);
		tokenizer = new StringTokenizer("");
	}

	private void eat(String s) {
		tokenizer = new StringTokenizer(s);
	}

	public String nextLine() {
		try {
			return reader.readLine();
		} catch (Exception e) {
			return null;
		}
	}

	public boolean hasNext() {
		while (!tokenizer.hasMoreTokens()) {
			String s = nextLine();
			if (s == null)
				return false;
			eat(s);
		}
		return true;
	}

	public String next() {
		hasNext();
		return tokenizer.nextToken();
	}

	public int nextInt() {
		return Integer.parseInt(next());
	}

	public long nextLong() {
		return Long.parseLong(next());
	}

	public double nextDouble() {
		return Double.parseDouble(next());
	}

	public BigInteger nextBigInteger() {
		return new BigInteger(next());
	}

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值