赤裸裸最小生成树,没啥说的,我用kruskal过的
/*
* Author : ben
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
#include <stack>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <functional>
#include <numeric>
#include <cctype>
using namespace std;
/*
* 输入非负整数
* 支持short、int、long、long long等类型(修改typec即可)。
* 用法typec a = get_int();返回-1表示输入结束
*/
typedef int typec;
typec get_int() {
typec res = , ch;
while (!((ch = getchar()) >= '' && ch <= '')) {
if (ch == EOF)
return -;
}
res = ch - '';
while ((ch = getchar()) >= '' && ch <= '')
res = res * + (ch - '');
return res;
}
//输入整数(包括负整数,故不能通过返回值判断是否输入到EOF,本函数当输入到EOF时,返回-1),用法int a = get_int2();
int get_int2() {
int res = , ch, flag = ;
while (!((ch = getchar()) >= '' && ch <= '')) {
if (ch == '-')
flag = ;
if (ch == EOF)
return -;
}
res = ch - '';
while ((ch = getchar()) >= '' && ch <= '')
res = res * + (ch - '');
if (flag == )
res = -res;
return res;
} const int MAXM = ;
const int MAXN = ;
typedef struct {
int s, e;
typec len;
} MyEdge;
int myset[MAXM], myheight[MAXM];
MyEdge edges[MAXN];
int N, M;
inline bool operator<(const MyEdge &e1, const MyEdge &e2) {
return e1.len < e2.len;
}
void initset() {
for (int i = ; i <= M; i++) {
myset[i] = i;
myheight[i] = ;
}
}
int myfind(int x) {
while (myset[x] != x) {
x = myset[x];
}
return x;
}
void mymerge(int a, int b) {
if (myheight[a] == myheight[b]) {
myheight[a]++;
myset[b] = a;
} else if (myheight[a] < myheight[b]) {
myset[a] = b;
} else {
myset[b] = a;
}
} int kruskal() {
int ret = , x, y, z;
sort(edges, edges + N);
initset();
for (int i = ; i < N; i++) {
x = edges[i].s;
y = edges[i].e;
z = edges[i].len;
if (myfind(x) == myfind(y)) {
continue;
}
mymerge(myfind(x), myfind(y));
ret += z;
}
return ret;
} int graph[][]; void buildgraph() {
int nn = get_int(), mm = get_int();
for (int i = ; i < nn; i++) {
for (int j = ; j < mm; j++) {
graph[i][j] = get_int();
}
}
M = nn * mm;
N = ;
for (int i = ; i < nn - ; i++) {
for (int j = ; j < mm - ; j++) {
edges[N].s = i * mm + j;
edges[N].e = i * mm + j + ;
edges[N].len = abs(graph[i][j] - graph[i][j + ]);
N++;
edges[N].s = i * mm + j;
edges[N].e = i * mm + mm + j;
edges[N].len = abs(graph[i][j] - graph[i + ][j]);
N++;
}
edges[N].s = i * mm + mm - ;
edges[N].e = i * mm + mm + mm - ;
edges[N].len = abs(graph[i][mm - ] - graph[i + ][mm - ]);
N++;
}
for (int j = ; j < mm - ; j++) {
edges[N].s = (nn - ) * mm + j;
edges[N].e = (nn - ) * mm + j + ;
edges[N].len = abs(graph[nn - ][j] - graph[nn - ][j + ]);
N++;
}
// printf("N = %d, M = %d\n", N, M);
} int main() {
// freopen("test.in.txt", "r", stdin);
int T = get_int();
for (int t = ; t <= T; t++) {
buildgraph();
printf("Case #%d:\n%d\n", t, kruskal());
}
return ;
}