雕刻时光

just do it……nothing impossible
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

最大生成树kruskal——pku3723

Posted on 2011-02-19 10:01  huhuuu  阅读(591)  评论(0编辑  收藏  举报
从点的角度考虑,因为要使男女的点都要经过,所以男的点要是加上女生的人数的人数,遍历只要生成最大生成树,树的路径和就是可以节约的钱了……kruskal+并查集,效率较高
ps:要是不加#include<iostream>的话,用c++提交会有错,g++就没事,所以用c++提交不要忘了加上#include<iostream>
View Code
#include<stdio.h>
#include
<algorithm>
#include
<iostream>
using namespace std;

int f[20005],k,n,m;
struct data
{
int v;
int to;
int w;
}edge[
50005];

int cmp(data a,data b)
{
return a.w>b.w;
}

int find(int pos)
{
if(f[pos]==-1) return pos;
return f[pos]=find(f[pos]);
}

int un(int a,int b)
{
int fa=find(a),fb=find(b);
if(fa==fb) return 0;
f[fa]
=fb; return 1;
}

void krus()
{
int add=0,i;
sort(
&edge[1],&edge[k+1],cmp);
for(i=1;i<=k;i++)
{
if(un(edge[i].v,edge[i].to)==1)
add
+=edge[i].w;
}
printf(
"%d\n",(n+m)*10000-add);
}

int main()
{
int i,j,t;
scanf(
"%d",&t);
while(t--)
{
scanf(
"%d%d%d",&n,&m,&k);

for(i=1;i<=n+m;i++)
f[i]
=-1;
for(i=1;i<=k;i++)
{
scanf(
"%d%d%d",&edge[i].v,&edge[i].to,&edge[i].w);
edge[i].v
+=1;
edge[i].to
+=n+1;
}

krus();
}
}