![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 # include<stdio.h> ///大部分与上几个理解有相似之处,我把不同的地方标注一下,便于理解
2 # include<stdlib.h>
3 # include<string.h>
4 # include<math.h>
5 double x[5000],y[5000];///存的是两个点的x,y左标
6 int flag[5000];
7 struct node
8 {
9 int num1,num2;///存的是两个点
10 double dis; ///存的是距离
11 };
12 node count[5000];
13 int cmp(const void *a,const void *b)
14 {
15 struct node *c = (struct node *)a;
16 struct node *d = (struct node *)b;
17 if(c->dis!=d->dis)
18 return c->dis>d->dis?1:-1;///double型排序,就是按距离排的序
19 else
20 return 1;
21 }
22 int find(int i)
23 {
24 if(flag[i]!=i)
25 return flag[i]=find(flag[i]);
26 return i;
27 }
28 void Merge(int x1,int y1)
29 {
30 int i,j;
31 i=find(x1);
32 j=find(y1);
33 if(i>j)
34 flag[i]=j;
35 else
36 flag[j]=i;
37 }
38 int main()
39 {
40 int i,j,n,k,k1,k2;
41 double sum;
42 while(scanf("%d",&n)!=EOF)
43 {
44 k=0;
45 memset(count,0,sizeof(count));
46 memset(x,0,sizeof(x));
47 memset(y,0,sizeof(y));
48 memset(flag,0,sizeof(flag));
49 for(i=1;i<=n;i++)
50 {
51 scanf("%lf%lf",&x[i],&y[i]); ///下面的处理,即i是第几个点,坐标后来就不理了,存的是距离了,i从1开始的
52 for(j=1;j<i;j++)
53 {
54 count[k].num1=i;
55 count[k].num2=j;
56 count[k].dis=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));///直接存的距离
57 k++;
58 }
59 }
60 for(i=1;i<=n;i++)
61 flag[i]=i;
62 qsort(count,k,sizeof(count[0]),cmp);
63 sum=0;
64 for(i=0;i<k;i++)
65 {
66 if(count[i].dis!=0) ///不用担心出现相同的点,这个if 和下个if足以处理掉
67 {
68 k1=find(count[i].num1);
69 k2=find(count[i].num2);
70 if(k1!=k2)
71 {
72 Merge(count[i].num1,count[i].num2);
73 sum=sum+count[i].dis;
74 }
75 }
76 }
77 printf("%.2f\n",sum);
78 }
79 return 0;
80 }