题目链接http://poj.org/problem?id=1258
使用快排将保存有一条线段两个端点和长度的结构体按长度进行排序,然后使用并查集查找两个端点是否已经被查找过,相比prim算法,kruskal算法生成最小树要好理解一点,简单来说,就是排序+并查集的应用来保证所有的点连接,并使权值之和最小
<span style="font-size:18px;">#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct map
{
int s,e,lenth;
}node[10010];
int n;
int nodeSet[110];
int top;
int cmp(const void *a ,const void *b)
{
struct map *p1 = (struct map *)a;
struct map *p2 = (struct map *)b;
return p1->lenth - p2->lenth;
}
int find(int x)
{
if(x==nodeSet[x])
return x;
else
return find(nodeSet[x]);
}
int kruskal()
{
int i;
int sum = 0;
for(i=1;i<=top;i++)
{
int a = find(node[i].s);
int b = find(node[i].e);
if(a != b)
{
nodeSet[a]=b;
sum+=node[i].lenth;
}
}
return sum;
}
int main()
{
while(~scanf("%d",&n))
{
int i,j;
top=0;
for(i=1; i<=n; i++)
{
nodeSet[i]=i;
for(j=1; j<=n; j++)
{
scanf("%d",&node[top].lenth);
node[top].s=i;
node[top].e=j;
top++;
}
}
// printf("%d\n",top);
qsort(node,top,sizeof(node[0]),cmp);
/*for(i=0;i<top;i++)
{
printf("%d ",node[i].lenth);
}*/
int result = kruskal();
printf("%d\n",result);
}
return 0;
}</span>