//http://ac.jobdu.com/problem.php?cid=1040&pid=71
1、给出的是坐标,所以默认第一个是点1,第二个是点2,保存在list[]中
2、n个点,得到m=n*(n-1)/2 条边,计算得到m条边的距离
3、保存m条边,a=1,b=2,则cost就是ab间距离
#include <stdio.h>
#include <math.h>
#include <algorithm>
using namespace std;
#define N 101
int Tree[N];
int findRoot(int x)
{
if (Tree[x]==-1)
{
return x;
}
else
{
int tmp=findRoot(Tree[x]);
Tree[x]=tmp;
return tmp;
}
}
struct Edge //边结构体
{
int a,b;
double cost;
bool operator< (const Edge &A) const //重载运算符,使边结构体能按权值从小到大排列
{
return cost<A.cost;
}
}edge[6000]; //不超过6000条边
struct Point //点结构体,保存点的坐标
{
double x,y;
}list[101]; //最多100个点
double getDistance(Point A,Point B) //得到两点间距离
{
double tmp=(A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y);
return sqrt(tmp);
}
int main()
{
int n,i,j;
while (scanf("%d",&n)!=EOF)
{
for (i=1;i<=n;i++)
{
scanf("%lf%lf",&list[i].x,&list[i].y); //输入第i个点坐标
}
int size=0; //抽象出边的总数
for (i=1;i<=n;i++)
{
for (j=i+1;j<=n;j++)//n个点,所以抽象出n*(n-1)/2条边,
{
edge[size].a=i; //边的两个顶点由i,j赋值
edge[size].b=j;
edge[size].cost=getDistance(list[i],list[j]); //计算权值
size++;
}
}
sort(edge,edge+size); //边号从0 ~ size,由小到大排序
for (i=1;i<=n;i++)
{
Tree[i]=-1;
}
double ans=0;
for (i=0;i<size;i++)
{
int a=findRoot(edge[i].a); //第i条边的两个顶点是否在一个集合
int b=findRoot(edge[i].b);
if (a!=b) //若不在,说明该小边是最小生成树中的一条边,ans(权值)累加
{
Tree[a]=b;
ans+=edge[i].cost;
}
}
printf("%.2lf\n",ans);
}
return 0;
}