看了半天发现原来是最小生成树啊......
先操作一次最小生成树,再看有几个集合,答案还需要加上集合数量*10000
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; const int maxn=50000; int T; int n,m,r; int f[maxn]; int num; int ans; struct Edge { int u,v; int cost; }e[maxn]; bool cmp(const Edge&a,const Edge&b) { return a.cost<b.cost; } int Find(int x) { if(x!=f[x]) f[x]=Find(f[x]); return f[x]; } void read() { scanf("%d%d%d",&n,&m,&r); for(int i=1;i<=r;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); a++;b++;c=10000-c; e[i].u=a; e[i].v=b+n; e[i].cost=c; } } void init() { for(int i=1;i<=n+m;i++) f[i]=i; num=n+m; ans=0; } void work() { sort(e+1,e+1+r,cmp); for(int i=1;i<=r;i++) { int fu=Find(e[i].u),fv=Find(e[i].v); if(fu!=fv) f[fu]=fv,num--,ans=ans+e[i].cost; } ans=ans+10000*num; printf("%d ",ans); } int main() { scanf("%d",&T); while(T--) { read(); init(); work(); } return 0; }