开始还以为最小生成树,结果最多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; }