运用kruskal算法的最大生成树的基础题,直接1A。
具体请参考:http://www.cnblogs.com/liangrx06/p/5083763.html
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,r;
struct Node{
int x,y,d;
}node[50000+5];
int par[20000+5];
bool cmp(Node x,Node y){return x.d>y.d;}
void init()
{
sort(node+1,node+r+1,cmp);//按d从大到小排列,以满足最大生成树的要求
for(int i=1;i<=n+m;i++) par[i]=i;//初始化并查集
}
int find(int x){return( par[x]==x ? x : par[x]=find(par[x]) );}
int kruskal()
{
int d_sum=0;
for(int i=1;i<=r;i++)
{
int x=find(node[i].x),y=find(node[i].y);
if(x != y)//找到一条属于最大生成树的新边
{
par[y]=x;//合并
d_sum+=node[i].d;//这条边属于最大生成树,即对应的题目中要使用的“关系”( ‵▽′)ψ
}
}
return d_sum;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("\n\n%d%d%d",&n,&m,&r);// n个girl , m个boy , r句话
for(int i=1;i<=r;i++)
{
int x,y,d;
scanf("\n%d%d%d",&x,&y,&d); //girl - x ; boy - y
node[i].x=x+1,node[i].y=n+1+y;//这样可以确保男女孩的编号必然是不同的
node[i].d=d;
}
init();
int d_sum=kruskal();
printf("%d\n",(n+m)*10000 - d_sum);
}
}