HDU 1301 并查集 和最小生成树
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
#define M 1000
typedef struct
{
int i,j,k;
}Node;
Node set[M]; //节点之间的代价,即带权的
int parent[28],v[28]; //v标记该节点是否出现在图中
int Match(char ch)
{
return ch-64;
}
int find(int x)
{
if(x!=parent[x]) parent[x]=find(parent[x]);
return parent[x];
}
int cmp(Node a,Node b)
{
return a.k<b.k;
}
void UnionSet(int x,int y)
{
x=find(x);
y=find(y);
if(x!=y) parent[x]=y;
}
int main()
{
int n,p,m,q,flag,x; //flag记录有关系的点对
char ch;
while((scanf("%d",&n)!=EOF)&& n )
{
int num=0; //num记录有多少个点在图中
flag=0;
memset(v,0,sizeof(v));
for(int i=1;i<28;i++) parent[i]=i;
while(--n) //总共有n行
{
while(scanf("%c",&ch)&&((ch<'A')||(ch>'Z')));
p=Match(ch);
if(v[p]==0)
{
v[p]=1;
num++;
}
scanf("%d",&q);
while(q--) //每行有q个数
{
while(scanf("%c",&ch)&&((ch<'A')||(ch>'Z')));
x=Match(ch);
if(v[x]==0)
{
num++;
v[x]=1;
}
set[flag].i=p;
set[flag].j=x;
scanf("%d",&(set[flag++].k));
}
}
sort(set,set+flag,cmp);
m=0;
//int k=num;
int total=0;
while(1)
{
if(num==1) break;
//cout<<"find(set[m].i)=="<<find(set[m].i)<<" find(set[m].j)"<<find(set[m].j)<<endl;
if(find(set[m].i)!=find(set[m].j))
{
num--;
UnionSet(set[m].i,set[m].j);
total+=set[m].k;
}
m++;
}
//for(int i=1;i<28;i++) cout<<i<<" ";
printf("%d\n",total);
}
return 0;
}
浙公网安备 33010602011771号