合肥工业大学oj 1005 诅咒教派

#include<iostream>
#include<queue>
using namespace std;

class field{//用存储节点的横纵坐标和腐蚀所需要花费的时间
    public:
        int x;
        int y;
        int time;
        field(int x, int y, int time){
            this->x = x;
            this->y = y;
            this->time = time;
        }
};
struct compare{//修改优先队列的排序规则,在所有正在被腐蚀的土地中,最先被腐蚀完全的一定是那些用时最少的,所以我们按照time升序排列
    bool operator()(field a, field b){
        return a.time > b.time;
    }
};

int main(){
    int m, n, x, y;
    int next[4][2]{{0, 1}, {1, 0}, {0, -1}, {-1, 0}};//为了遍历一个点的上下左右相邻的四个点
    while(cin >> m >> n >> x >> y){
        int map[m][n];
        bool isvisited[m][n];
        priority_queue<field, vector<field>, compare> pq;//声明优先队列
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                cin >> map[i][j];//建立地图
                isvisited[i][j] = false;//将isvisited数组初始化
            }
        }
        isvisited[x][y] = true;//出发点设置为已经访问过
        pq.push(field(x, y, map[x][y]));//将出发点放进队列中
        int total = 0;//用于记录总时间
        while(!pq.empty()){//在每轮循环中,队列存储的就是目前正在被腐蚀的土地
            int cur_x = pq.top().x;
            int cur_y = pq.top().y;
            int cur_time = pq.top().time;//取出队首(即最快被腐蚀干净的土地)
            total += cur_time;
            pq.pop();//删除这个土地
            int len = pq.size();//记录队列的大小,为了在下面的循环中使用
            priority_queue<field, vector<field>, compare> temp;//开另外一个用来辅助的数组
            for(int i = 0; i < len; i++){
                temp.push(field(pq.top().x, pq.top().y, pq.top().time - cur_time));//把pq数组的土地取出来减去cur_time再放进temp中,因为cur_time已经消耗掉了
                pq.pop();//删除掉已经使用过的
            }
            pq = temp;//别忘了再赋值回去
            for(int i = 0; i < 4; i++){//将被删除土地的上下左右土地能够被腐蚀的放进数组中
                int next_x = cur_x + next[i][0];
                int next_y = cur_y + next[i][1];
                if((next_x >= 0 && next_x < m) && (next_y >= 0 && next_y < n) && !isvisited[next_x][next_y]){//判断被删除土地的上下左右土地能否被腐蚀
                    isvisited[next_x][next_y] = true;
                    pq.push(field(next_x, next_y, map[next_x][next_y]));
                }
            }
        }
        cout << total << endl;//输出答案
    }

    return 0;
}
//presented by 大吉大利,今晚AC

猜你喜欢

转载自blog.csdn.net/lalala_HFUT/article/details/87204509