2 4 3 9 12 4 7 8 56 32 32 43 21 12 12 2 3 34 56 56 12 23 4
Case #1: 82 Case #2: 74
模板套一套就好了。
#include <algorithm> #include <cstdio> #include <cstdlib> #include <cstring> using namespace std; const int MAXC = 1002, MAXN = 1000001, MAXM = MAXN << 1, dx[] = {0, 0, -1, 1}, dy[] = {-1, 1, 0, 0}; int n, m, a[MAXC][MAXC], f[MAXN]; struct edge { int x, y, z; inline bool operator <(const edge &t) const { return z < t.z; } } e[MAXM]; int find(int x) { return f[x] == x ? x : f[x] = find(f[x]); } inline int id(int x, int y) { return x >= 1 && x <= n && y >= 1 && y <= m ? (x - 1) * m + y : 0; //把原本用i,j两个值表示的下标用一个值表示 } inline void work() { scanf("%d%d", &n, &m); int idx = n * m, tot = 0, ans = 0; for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) scanf("%d", &a[i][j]); for (int i = 1; i <= idx; ++i) f[i] = i; for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) for (int k = 0; k < 4; ++k) { int x = i + dx[k], y = j + dy[k]; if (id(i, j) < id(x, y)) { e[tot].x = id(i, j); e[tot].y = id(x, y); e[tot++].z = abs(a[i][j] - a[x][y]); } } sort(e, e + tot); for (int i = 0; i < tot; ++i) { int x = find(e[i].x), y = find(e[i].y); if (x != y) { ans += e[i].z; f[x] = y; } } printf("%d\n", ans); } int main() { int t; scanf("%d", &t); for (int cs = 1; cs <= t; ++cs) { printf("Case #%d:\n", cs); work(); } return 0; }