王道机试练习——连接坐标点找最短距离
题目描述
为平面上有若干个点,我们需要用一些线段来将这些点连接起来使 任意两个点能够通过一系列的线段相连,给出所有点的坐标,求一种连接方式使 所有线段的长度和最小,求该长度和。 若我们将平面上的点抽象成图上的结点,将结点间直接相邻的线段抽象成连 接结点的边,且权值为其长度,那么该类似于几何最优值的问题就被我们转化到 了图论上的最小生成树问题。但在开始求最小生成树前,我们必须先建立该图, 得出所有的边和相应的权值。
代码
#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];
struct Point {
double x, y;
double getDistance(Point A) {
double tmp = (x - A.x)* (x - A.x) + (y - A.y)* (y - A.y);
return sqrt(tmp);
}
}list[101];
int main() {
int n;
while (scanf("%d", &n) != EOF) {
for (int i = 1; i <= n; i++) {
scanf("%lf%lf", &list[i].x, &list[i].y);
}
int size = 0;
for (int i = 1; i <= n; i++) {
for (int j = i + 1; j <= n; j++) {
edge[size].a = i;
edge[size].b = j;
edge[size].cost = list[i].getDistance(list[j]);
size++;//边的总数增加
}
}
sort(edge ,edge + size);
for (int i = 1; i <= n; i++) {
Tree[i] = -1;
}
double ans = 0;
for (int i = 0; i < size; i++) {
int a, b;
a = findRoot(edge[i].a);
b = findRoot(edge[i].b);
if (a != b) {
Tree[a] = b;
ans += edge[i].cost;
}
}
printf("%.2lf\n", ans);//后面精度为两位小数
}
return 0;
}