#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