乱搞版:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define W 305
#define H 305
#define B 1000000001
#define STOP system("pause")
inline int max(int a, int b){ return a > b ? a : b; }
inline int min(int a, int b){ return a < b ? a : b; }
const int dir[][2] = { {0, 1}, {0, -1}, {1, 0}, {-1, 0} };
int height[H][W], maps[H][W];
int w, h, maxb, ans;
void updata(int x, int y)
{
if(x <= 0 || y <= 0 || x >= h-1 || y >= w-1)
return;
int tx, ty, temp;
int minh = B;
for(int i=0; i<4; i++)
{
tx = x + dir[i][0];
ty = y + dir[i][1];
minh = min(height[tx][ty], minh);
}
temp = max(minh, maps[x][y]);
if(temp == height[x][y])
return;
if(temp < height[x][y])
{
ans -= height[x][y] - temp;
height[x][y] = temp;
}
for(int i=0; i<4; i++)
{
tx = x + dir[i][0];
tx = y + dir[i][1];
if(height[tx][ty] > height[x][y])
{
updata(tx, ty);
}
}
}
int main()
{
while( scanf("%d %d", &w, &h) != EOF )
{
maxb = ans = 0;
for(int i=0; i<h; i++)
for(int j=0; j<w; j++)
{
scanf("%d", &maps[i][j]);
if(maps[i][j] > maxb)
maxb = maps[i][j];
}
for(int i=0; i<h; i++)
for(int j=0; j<w; j++)
height[i][j] = maxb;
for(int i=0; i<h; i++)
{
height[i][0] = maps[i][0];
height[i][w-1] = maps[i][w-1];
}
for(int i=0; i<w; i++)
{
height[0][i] = maps[0][i];
height[h-1][i] = maps[h-1][i];
}
for(int i=0; i<h; i++)
for(int j=0; j<w; j++)
if(height[i][j] > maps[i][j])
ans += height[i][j] - maps[i][j];
int temp = -1;
while(temp != ans)
{
temp = ans;
for(int c=1; c < max(h, w)/2; c++)
/*int c = 1;*/
{
for(int i=c; i<w-c; i++)
{
updata( c, i );
updata( c, w-i-1);
updata(h-c-1, i );
updata(h-c-1, w-i-1);
}
for(int i=c; i<h-c; i++)
{
updata( i, c );
updata(h-i-1, c );
updata( i, w-c-1);
updata(h-i-1, w-c-1);
}
/*
for(int i=w-c-1; i>=c; i--)
{
updata( c, i);
updata(h-c-1, i);
}
for(int i=h-c-1; i>=c; i--)
{
updata( i, c );
updata( i, w-c-1);
}
*/
}
}
/*
for(int i=0; i<h; i++)
{
for(int j=0; j<w; j++)
printf("%d ", height[i][j]);
printf("\n");
}
*/
printf("%d\n", ans);
}
return 0;
}
单调队列:
#include <cstdio>
#include <iostream>
#include <assert.h>
#include <cstring>
using namespace std;
class PQ
{
public:
PQ(bool (*callback)(void* a, void* b) = defaultCallback);
bool insertKey(void* key);
bool removeKey(void* key);
bool isEmpty();
void* topKey();
void* popTopKey();
void setCallback( bool (*callback)(void* a, void* b));
void println(char* (*print)(void *));
private:
static const int HeapSize = 90005;
static bool defaultCallback(void* a, void *b);
int leftSon(int k);
int rightSon(int k);
int parent(int k);
void heapify(int k);
bool updataKey(int pos, void* newkey);
int size;
void* a[HeapSize];
bool (*callback)(void* a, void* b);
};
PQ::PQ(bool (*_callback)(void* a, void* b))
{
callback = _callback;
size = 0;
}
bool PQ::isEmpty()
{
return size == 0 ? true : false;
}
bool PQ::defaultCallback(void* a, void* b)
{
return *(int*)a < *(int*)b;
}
inline int PQ::leftSon(int k) { return k<<1; }
inline int PQ::rightSon(int k) { return (k<<1)+1;}
inline int PQ::parent(int k) { return k>>1; }
void PQ::heapify(int k)
{
while(true)
{
int l = leftSon(k);
int r = rightSon(k);
int m = k;
if(l <= size && callback(a[l], a[m]) ) m = l;
if(r <= size && callback(a[r], a[m]) ) m = r;
if(m == k) return;
swap(a[m], a[k]);
//printf("~ swap %d %d\n", m, k);
//heapify(m);
k = m;
}
}
bool PQ::insertKey(void *key)
{
size++;
updataKey(size, key);
return true;
}
bool PQ::updataKey(int pos, void *newkey)
{
a[pos] = newkey;
//cout << "~ " << pos << " " << *(int*)newkey << endl;
heapify(pos);
while(pos > 1 && callback(a[pos], a[ parent(pos) ]) )
{
swap(a[pos], a[ parent(pos) ]);
pos = parent(pos);
}
return true;
}
void* PQ::topKey()
{
return a[1];
}
void* PQ::popTopKey()
{
assert(size != 0);
void* v = a[1];
swap(a[1], a[size]);
size--;
heapify(1);
return v;
}
bool PQ::removeKey(void *key)
{
//TODO!
assert(size != 0);
return false;
}
void PQ::println(char* (*print)(void *))
{
for(int i=1; i<=size; i++)
printf(" ~%3d: %s\n", i, print(a[i]));
// printf("\n");
}
class Point
{
public:
int w, h, b, B;
bool v;
void init(int w, int h)
{
this->v = false;
this->w = w;
this->h = h;
this->B = 110000000;
}
};
char* printPoint(void* a)
{
static char s[100];
sprintf(s, "(%d, %d : %d)", ((Point*)a)->h, ((Point*)a)->w, ((Point*)a)->b);
//printf("(%d, %d)", ((Point*)a)->h, ((Point*)a)->w);
return s;
}
bool callback(void *a, void *b)
{
return ((Point*)a)->B < ((Point*)b)->B ;
}
#define W 305
#define H 305
int w, h;
Point maze[H][W];
static const int dxdy[][2] = { {0, 1}, {0, -1}, {1, 0}, {-1, 0} };
bool checkPoint(int tw, int th)
{
if(tw < 1 || tw > w-2) return false;
if(th < 1 || th > h-2) return false;
if(maze[th][tw].v == true) return false;
return true;
}
int main()
{
while( scanf("%d%d", &w, &h) != EOF)
{
for(int i=0; i<h; i++)
for(int j=0; j<w; j++)
{
scanf("%d", &maze[i][j].b);
maze[i][j].init(j, i);
}
PQ p(callback);
for(int i=1; i<h-1; i++)
{
maze[i][0].v =
maze[i][w-1].v = true;
maze[i][0].B = maze[i][0].b;
maze[i][w-1].B = maze[i][w-1].b;
p.insertKey(&maze[i][0]);
p.insertKey(&maze[i][w-1]);
}
for(int i=1; i<w-1; i++)
{
maze[0][i].v =
maze[h-1][i].v = true;
maze[0][i].B = maze[0][i].b;
maze[h-1][i].B = maze[h-1][i].b;
p.insertKey(&maze[0][i]);
p.insertKey(&maze[h-1][i]);
}
//p.println(printPoint);
while( p.isEmpty() == false)
{
Point top = *(Point*)p.topKey();
//printf("top key is (%d %d) %d %d\n", top.h, top.w, top.b, top.B);
for(int i=0; i<4; i++)
{
int w = top.w+dxdy[i][0];
int h = top.h+dxdy[i][1];
if(checkPoint(w, h))
{
if(maze[h][w].B == maze[h][w].b) continue;
if(maze[h][w].B > top.B )
{
if(maze[h][w].b <= top.B) maze[h][w].B = top.B;
else maze[h][w].B = maze[h][w].b;
p.insertKey(&maze[h][w]);
maze[h][w].v = true;
}
}
}
//printMaze();
p.popTopKey();
top.v = false;
}
int ans = 0;
for(int i=1; i<h-1; i++)
for(int j=1; j<w-1; j++)
{
ans += maze[i][j].B - maze[i][j].b;
}
cout << ans << endl;
}
return 0;
}
单调队列stl:
#include <cstdio>
#include <iostream>
#include <assert.h>
#include <cstring>
#include <queue>
using namespace std;
class Point
{
public:
int w, h, b, B;
bool v;
void init(int w, int h)
{
this->v = false;
this->w = w;
this->h = h;
this->B = 110000000;
}
};
struct Cmp
{
bool operator()(Point* a, Point* b)
{
return a->B > b->B;
}
};
#define W 305
#define H 305
int w, h;
Point maze[H][W];
static const int dxdy[][2] = { {0, 1}, {0, -1}, {1, 0}, {-1, 0} };
inline bool checkPoint(int tw, int th)
{
if(tw < 1 || tw > w-2) return false;
if(th < 1 || th > h-2) return false;
if(maze[th][tw].v == true) return false;
return true;
}
int main()
{
while( scanf("%d%d", &w, &h) != EOF)
{
for(int i=0; i<h; i++)
for(int j=0; j<w; j++)
{
scanf("%d", &maze[i][j].b);
maze[i][j].init(j, i);
}
priority_queue<Point*, vector<Point*>, Cmp> pq;
for(int i=1; i<h-1; i++)
{
maze[i][0].v =
maze[i][w-1].v = true;
maze[i][0].B = maze[i][0].b;
maze[i][w-1].B = maze[i][w-1].b;
pq.push(&maze[i][0]);
pq.push(&maze[i][w-1]);
}
for(int i=1; i<w-1; i++)
{
maze[0][i].v =
maze[h-1][i].v = true;
maze[0][i].B = maze[0][i].b;
maze[h-1][i].B = maze[h-1][i].b;
pq.push(&maze[0][i]);
pq.push(&maze[h-1][i]);
}
while( pq.empty() == false )
{
Point top = *(Point*)pq.top();
for(int i=0; i<4; i++)
{
int w = top.w+dxdy[i][0];
int h = top.h+dxdy[i][1];
if(checkPoint(w, h))
{
if(maze[h][w].B == maze[h][w].b) continue;
if(maze[h][w].B > top.B )
{
if(maze[h][w].b <= top.B) maze[h][w].B = top.B;
else maze[h][w].B = maze[h][w].b;
pq.push(&maze[h][w]);
maze[h][w].v = true;
}
}
}
pq.pop();
top.v = false;
}
int ans = 0;
for(int i=1; i<h-1; i++)
for(int j=1; j<w-1; j++)
{
ans += maze[i][j].B - maze[i][j].b;
}
cout << ans << endl;
}
return 0;
}