题目72:Freckles

//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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值