//7983483 vrs 2227 Accepted 1120K 235MS C++ 2852B 2010-12-08 20:02:00
//POJ 2227 凹凸坑装水 优先队列(堆)+floodfill(bfs)
//黑书中的一道题 先分析边界点,弄为障碍物,把他们放到堆里,然后从最小的开始,进行一次floodfill(木桶原理)
//一直循环直到堆为空,每次floodfill是使用队列做一次广搜
#include<stdio.h>
#include<queue>
using namespace std;
#define bool int
#define MAXNUM 90005
typedef struct _BLOCK
{
long key;
int row;
int col;
}BLOCK;
BLOCK block[MAXNUM];
long n;
long map[305][305];
bool mapState[305][305];
int director[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
unsigned long long sumJuice;
queue <BLOCK> *qu;
void swap(long i,long j)
{
BLOCK temp;
//这里尝试了用memcpy,感觉不错
memcpy(&temp,&block[i],sizeof(BLOCK));
memcpy(&block[i],&block[j],sizeof(BLOCK));
memcpy(&block[j],&temp,sizeof(BLOCK));
/*
temp.key=block[i].key;
temp.col=block[i].col;
temp.row=block[i].row;
block[i].key=block[j].key;
block[i].row=block[j].row;
block[i].col=block[j].col;
block[j].key=temp.key;
block[j].row=temp.row;
block[j].col=temp.col;*/
}
void Insert(long data,int row,int col)
{
long father,son;
n++;
block[n].key=data;
block[n].row=row;
block[n].col=col;
son=n;
while(son>1)
{
father=son/2;
if(block[father].key>block[son].key)
swap(father,son);
else
break;
son=father;
}
}
long Top()
{
return 1;
}
bool IsEmpty()
{
if(n==0)
return 1;
else
return 0;
}
void Pop()
{
long father,son;
swap(1,n);
n--;
father=1;
while(father<=n/2)
{
son=father*2;
if(son+1<=n && block[son].key>block[son+1].key)
son++;
if(block[father].key>block[son].key)
swap(father,son);
else
break;
father=son;
}
}
//就是一个bfs
void FloodFill(int rowNum,int colNum)
{
int i,row,col;
BLOCK curBlock,tempBlock;
while(!qu->empty())
{
curBlock=qu->front();
qu->pop();
for(i=0;i<4;i++)
{
row=curBlock.row+director[i][0];
col=curBlock.col+director[i][1];
if(row>0 && row<rowNum-1 && col>0 && col<colNum-1 && !mapState[row][col])
{
mapState[row][col]=1;
if(curBlock.key<map[row][col])
Insert(map[row][col],row,col);
else
{
if(curBlock.key-map[row][col]>0)
sumJuice+=(unsigned long long)(curBlock.key-map[row][col]);
tempBlock.key=curBlock.key;
tempBlock.row=row;
tempBlock.col=col;
qu->push(tempBlock);
}
}
}
}
}
void Init(int col,int row)
{
int i,j;
memset(mapState,0,sizeof(mapState));
n=0;
sumJuice=0;
qu=new queue<BLOCK>;
for(j=1;j<col-1;j++)
{
Insert(map[0][j],0,j);
mapState[0][j]=1;
Insert(map[row-1][j],row-1,j);
mapState[row-1][j]=1;
}
for(i=1;i<row-1;i++)
{
Insert(map[i][0],i,0);
mapState[i][0]=1;
Insert(map[i][col-1],i,col-1);
mapState[i][col-1]=1;
}
mapState[0][0]=1;
mapState[0][col-1]=1;
mapState[row-1][0]=1;
mapState[row-1][col-1]=1;
}
int main()
{
int colNum,rowNum;
int i,j;
int curPos;
scanf("%d%d",&colNum,&rowNum);
for(i=0;i<rowNum;i++)
for(j=0;j<colNum;j++)
scanf("%ld",&map[i][j]);
Init(colNum,rowNum);
while(!IsEmpty())
{
curPos=Top();
qu->push(block[curPos]);
FloodFill(rowNum,colNum);
Pop();
}
printf("%lld\n",sumJuice);
delete qu;
return 0;
}
/*一个测试数据
13 6
5 8 7 7 1 2 4 3 2 4 6 8 9
5 2 1 5 1 5 7 1 2 6 5 4 8
7 5 5 1 4 8 6 5 2 1 8 9 2
8 9 6 9 1 5 2 5 8 6 2 1 4
9 8 9 9 4 8 5 2 4 8 9 6 2
1 5 2 5 2 6 8 5 4 7 8 2 3
answer=28