PS: 分析这是一道不错的题目,要求去抽象。
直接说结论: 题目可能是许森林,每一个森林有一颗最小生成树并且选择第一个点花费为10000。
这道题目实现的时候我对0 ~ M进行了编码为 N 到 M+N-1。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int MAXN = 20010;
struct edge {
int from, to, w;
};
vector<edge> edges;
int f[MAXN];
int N, M, R;
bool cmp(edge x, edge y) {
if(x.w != y.w) return x.w < y.w;
else return false;
}
int getFather(int x) {
if(f[x] == x) return x;
else return f[x] = getFather(f[x]);
}
int work() {
const int bound = N+M;
for(int i = 0; i < bound; i++) f[i] = i;
sort(edges.begin(), edges.end(), cmp);
long long tot = 0;
for(int i = 0; i < (int)edges.size(); i++) {
edge &t = edges[i];
int f1 = getFather(t.from);
int f2 = getFather(t.to);
if(f1 != f2) {
f[f1] = f2;
tot += t.w;
}
}
int cnt = 0;
for(int i = 0; i < bound; i++) {
if(f[i] == i) cnt++;
}
return 10000*cnt + tot;
}
int main()
{
int T;
scanf("%d", &T);
while(T--) {
scanf("%d%d%d", &N, &M, &R);
edges.clear();
int x, y, w;
edge t;
for(int i = 1; i <= R; i++) {
scanf("%d%d%d", &x, &y, &w);
w = 10000-w;
y = y + N; // encoding.
t.from = x;
t.to = y;
t.w = w;
edges.push_back(t);
}
int res = work();
printf("%d\n", res);
}
return 0;
}