从外面一点一点往里面拓展(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 #include <cstdio> 11 #include <queue> 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 <data> 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 }
时间: 2024-09-30 18:54:38