从外面一点一点往里面拓展(floodfill),每次找出最小的一个点,计算它对答案的贡献就好了。。。
找最小的点的话,直接pq就行
1 /************************************************************** 2 Problem: 1736 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:196 ms 7 Memory:2116 kb 8 ****************************************************************/ 9 10 #include11 #include 12 13 using namespace std;14 typedef long long ll;15 const int N = 305;16 const int dx[] = { 0, 0, 1, -1};17 const int dy[] = { 1, -1, 0, 0};18 19 inline int read();20 21 struct data {22 int x, y, h;23 data(int _x = 0, int _y = 0, int _h = 0) : x(_x), y(_y), h(_h) {}24 25 inline bool operator < (const data &d) const { 26 return h > d.h;27 }28 };29 30 int n, m;31 int mp[N][N], v[N][N];32 priority_queue h;33 34 inline ll work(){35 ll res = 0;36 int x, y, k;37 data now;38 while (!h.empty()) {39 now = h.top(), h.pop();40 for (k = 0; k < 4; ++k) {41 x = now.x + dx[k], y = now.y + dy[k];42 if (x <= 0 || y <= 0 || x > n || y > m || v[x][y]) continue;43 v[x][y] = 1;44 if (mp[x][y] < now.h)45 res += now.h - mp[x][y], mp[x][y] = now.h;46 h.push(data(x, y, mp[x][y]));47 }48 }49 return res;50 }51 52 int main() {53 int i, j;54 m = read(), n = read();55 for (i = 1; i <= n; ++i)56 for (j = 1; j <= m; ++j) mp[i][j] = read();57 for (i = 1; i <= n; ++i)58 for (j = 1; j <= m; ++j)59 if (i == 1 || j == 1 || i == n || j == m)60 h.push(data(i, j, mp[i][j])), v[i][j] = 1;61 printf("%lld\n", work());62 return 0;63 }64 65 inline int read() {66 static int x;67 static char ch;68 x = 0, ch = getchar();69 while (ch < '0' || '9' < ch)70 ch = getchar();71 while ('0' <= ch && ch <= '9') {72 x = x * 10 + ch - '0';73 ch = getchar();74 }75 return x;76 }