题目大意:
给出N个点的坐标,对它们建立一个最小生成树,代价就是连接它们的路径的长度,现要求总长度最小。N的值在100以内,坐标值在[-10000,10000].结果保留二位小数。
思路:
这道题比其他的树要麻烦一些,它不是给出每两个点之间的距离,而是给出每个点的坐标,它们之间的距离需要我们运用勾股定理自己去求!
勾股定理:
若该三角形为直角三角形,且a和b为两条直角边,则:
a^2+b^2=c^2
运用勾股定理就可以求出两个点之间的距离。
求出距离后就能用最基础的方法去做啦!
代码:
#include <cstdio>
#include <iostream>
#include <cmath>
using namespace std;
double a[101][101],x[101],y[101],c[101],minn,sum;
int n,b[20001],k;
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%lf%lf",&x[i],&y[i]);
for (int j=1;j<=i-1;j++)
a[i][j]=a[j][i]=sqrt(abs(x[i]-x[j])*abs(x[i]-x[j])+abs(y[i]-y[j])*abs(y[i]-y[j])); //求两点之间的距离
}
b[1]=1; //进入集合
for (int i=2;i<=n;i++)
{
if (a[1][i]!=0) c[i]=a[1][i]; //集合外的点到集合的最短距离
}
for (int q=1;q<=n-1;q++)
{
minn=2147483647;
for (int i=1;i<=n;i++)
{
if (c[i]!=0&&c[i]<minn&&b[i]==0) //如果有一个集合外的点距离集合内的点更近
{
minn=c[i];
k=i;
}
}
b[k]=1; //进入集合
sum+=c[k];
c[k]=0;
for (int i=1;i<=n;i++)
{
if ((c[i]==0&&a[k][i]!=0&&b[i]==0)||a[k][i]<c[i]) //重新计算集合外的点到集合的最短距离
c[i]=a[k][i];
}
}
printf("%0.2lf\n",sum);
return 0;
}