开始还以为最小生成树,结果最多8个节点,明显是要暴力枚举。
先递归生成每种排列,计算距离总和,记录下最小的,最后输出。
#include<stdio.h>
#include<math.h>
#include<string.h>
typedef struct Point {
int x;
int y;
} Point;
Point point[8];
int n;
double minLen;
int minPerm[8];
int perm[8];
void permu(int cur) {
if (cur == n) {
int i;
/* for (i = 0; i < n; i++)
printf("%d ", perm[i]);
printf("\n");
*/
double curLen = 0;
for (i = 0; i < n - 1; i++) {
curLen += sqrt(
pow(point[perm[i]].x - point[perm[i + 1]].x, 2)
+ pow(point[perm[i]].y - point[perm[i + 1]].y, 2))
+ 16;
}
if (curLen < minLen) {
minLen = curLen;
memcpy(minPerm, perm, sizeof(perm));
}
return;
} else {
int i, j;
for (i = 0; i < n; i++) {
int exist = 0;
for (j = 0; j < cur; j++)
if (perm[j] == i) {
exist = 1;
break;
}
if (!exist) {
perm[cur] = i;
permu(cur + 1);
}
}
}
}
int main() {
int cases = 1;
while (scanf("%d", &n)) {
if (n == 0)
break;
minLen = 0x7fffffff;
memset(minPerm, 0, sizeof(minPerm));
int i;
for (i = 0; i < n; i++)
scanf("%d%d", &point[i].x, &point[i].y);
permu(0);
printf("**********************************************************\n");
printf("Network #%d\n", cases++);
double len = 0;
for (i = 0; i < n - 1; i++) {
len = sqrt(
pow(point[minPerm[i]].x - point[minPerm[i + 1]].x, 2)
+ pow(point[minPerm[i]].y - point[minPerm[i + 1]].y,
2)) + 16;
printf(
"Cable requirement to connect (%d,%d) to (%d,%d) is %.2lf feet.\n",
point[minPerm[i]].x, point[minPerm[i]].y,
point[minPerm[i + 1]].x, point[minPerm[i + 1]].y, len);
}
printf("Number of feet of cable required is %.2lf.\n", minLen);
}
return 0;
}
本文介绍了一种通过暴力枚举方法解决最小生成树问题的算法实现,针对最多8个节点的情况,采用递归生成排列,计算距离总和,记录最小路径。
114

被折叠的 条评论
为什么被折叠?



