NEFU-越狱(Kruskal,建图技巧)
Description
有一批人质关在一个n*m的“网格”监狱中,每个网格中关押着一名人质,每个格子四面都是混凝土墙壁,作为超级英雄的你要去解救这批人质,已知破坏每一堵墙的花费,求解救所有人质的最小花费。
Input
T组数据,第一行一个数字T,第二行两个数 n,m(n,m<=500),然后有一个(n+1)*m的矩阵,表示的是整个监狱的所有横向的墙需要的花费,然后是一个n*(m+1)矩阵,表示整个监狱的所有纵向的墙的花费,矩阵里的数字都小于100且都是整数。
Output
对于每一个样例,输出 最小花费。
Sample Input
1 2 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
Sample Output
6
Hint
Source
解析:
提供几个样例,其中第三个样例的情况我第一次没想到
1
2 3
2 2 2
1 1 1
2 2 2
2 1 1 2
2 1 1 2
2 3
2 2 2
3 1 3
2 2 2
2 4 1 2
2 1 2 2
2 3
2 2 2
3 6 3
2 2 2
2 4 1 2
2 2 2 2
#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<math.h>
#include<map>
using namespace std;
typedef long long LL;
const int N = 5e2 + 5,M=1e6+1000;
int n, m;
int arr[2][N][N], idx[N][N];
struct e {
int a, b, c;
}e[3 * N * N];
LL fa[M];
int cmp(const struct e& a, const struct e& b) {
return a.c < b.c;
}
int find(int a) {
if (fa[a] == a)return a;
return fa[a] = find(fa[a]);
}
int main() {
for (int i = 0, t = 0; i <= N - 2; i++) {
for (int j = 0; j <= N - 2; j++, t++) {
idx[i][j] = t;
}
}
int T;
cin >> T;
while (T--) {
int cnt = 0;
scanf("%d%d", &n, &m);
for (int i = 0; i <= n; i++) {
for (int j = 1; j <= m; j++) {
scanf("%d", &arr[0][i][j]);
if (i == 0) {
e[++cnt] = { 0,idx[i + 1][j],arr[0][i][j] };
}
else if (i == n) {
e[++cnt] = { 0,idx[i][j],arr[0][i][j] };
}
else {
e[++cnt] = { idx[i][j],idx[i + 1][j],arr[0][i][j]};
}
}
}
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= m; j++) {
scanf("%d", &arr[1][i][j]);
if (j == 0) {
e[++cnt] = { 0,idx[i][j+1],arr[1][i][j] };
}
else if (j == m) {
e[++cnt] = { 0,idx[i][j],arr[1][i][j] };
}
else {
e[++cnt] = { idx[i][j],idx[i][j + 1],arr[1][i][j]};
}
}
}
sort(e + 1, e + 1 + cnt, cmp);
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= m; j++)
fa[idx[i][j]] = idx[i][j];
}
LL ans = 0;
for (int i = 1; i <= cnt; i++) {
int a = find(e[i].a), b = find(e[i].b);
LL w = e[i].c;
if (a != b) {
ans += w;
fa[a] = b;
}
}
cout << ans << endl;
}
return 0;
}