求最大生成树,然后用总值m+n)*10000减去即可
也可以重新构造这个图,新加一个虚拟的点,到所有点都有边,权值为10000,然后原有的边的权值由v变为10000-v,直接求最小生成树
#include <cstdio>
#include <algorithm>
#include <functional>
using namespace std;
struct DisjoinSet {
int a[20010];
void clear(int n) {
for (int i=0;i<=n;i++) a[i]=i;
}
int get(int i) {
if (a[i]==i) return i;
return a[i]=get(a[i]);
}
void tosame(int x,int y) {
a[get(x)]=a[get(y)];
}
};
struct Edge {
int x,y,val;
void set(int a,int b,int c) {
x=a;y=b;val=c;
}
friend bool operator < (const Edge &a,const Edge &b) {
return a.val>b.val;
}
};
int n,m,r;
Edge b[5000010];
DisjoinSet c;
int main() {
int i,j,x,y,z,t,ans;
scanf("%d",&t);
while (t--) {
scanf("%d%d%d",&n,&m,&r);
c.clear(n+m);
for (i=0;i<r;i++) {
scanf("%d%d%d",&x,&y,&z);
b[i].set(x,y+n,z);
}
sort(b,b+r);
ans=0;
for (i=0;i<r;i++) {
if (c.get(b[i].x)!=c.get(b[i].y)) {
ans+=b[i].val;
c.tosame(b[i].x,b[i].y);
}
}
printf("%d\n",(m+n)*10000-ans);
}
return 0;
}