题目实质是求最小生成树,用Kruskal算法。
一、把原始图的N个节点看成N个独立子图;
二、每次选取当前最短的边(前提操作是?),看两端是否属于不同的子图;若是,加入;否则,放弃;
三、循环操作该步骤二,直到有N-1条边;
AC代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define NUM 10005
int set[NUM];
struct point
{
int begin;
int end;
int dis;
}points[NUM];
int cmp(const void *a, const void *b)
{
struct point *x=(struct point *)a;
struct point *y=(struct point *)b;
return x->dis - y->dis;
}
void init()
{
for(int i=0;i<=NUM;i++){
set[i]=i;
}
memset(points,0,sizeof(points));
}
int find(int x)
{
int r=x;
while(r!=set[r])
r=set[r];
return r;
}
void merge(int a, int b)
{
int x=find(a);
int y=find(b);
if(x!=y)
set[y]=x;
}
int main()
{
int n,m,i,j,a,b,val,ans;
freopen("C:\\Documents and Settings\\Administrator\\桌面\\input.txt","r",stdin);
while(scanf("%d",&n)!=EOF&&n!=0){
m=n*(n-1)/2;
init();
for(i=0;i<m;i++){
scanf("%d%d%d",&a,&b,&val);
points[i].begin=a;
points[i].end=b;
points[i].dis=val;
}
qsort(points,m,sizeof(points[0]),cmp);
j=0;
ans=0;
i=0;
for(j=0;j<m;j++){
if(i==n-1)//当解边集为n-1条时,跳出;之前就是因为这个WA
break;
a=points[j].begin;
b=points[j].end;
if(find(a)!=find(b)){
merge(a,b);
ans+=points[j].dis;
i++;
}
}
printf("%d\n",ans);
}
return 0;
}