全排列,每次计算距离,记录最小值
如果数据量再大些的话,可以用递归进行全排列,及时计算距离并与当前最小值对比,并减枝,在这里就不实现啦~
另外不知道为什么在Uva里一用宏就RE,只能把swap和dis改成函数定义了。。。
#include <stdio.h>
#include <string.h>
#include <math.h>
void swap(int* a, int *b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
double dis(double xi, double yi, double xj, double yj) {
return sqrt((xi-xj)*(xi-xj) + (yi-yj)*(yi-yj));
}
int nextPermutation(int a[], int n) {
int i, j;
for (i=n-1 ; i>=1 ; i--)
if (a[i-1] < a[i])
break;
if (i == 0)
return 0;
for (j=i+1 ; j<n ; j++)
if (a[j] <= a[i-1])
break;
swap(&a[i-1], &a[j-1]);
for (j=n-1 ; i<j ; i++, j--)
swap(&a[i], &a[j]);
return 1;
}
int main() {
int n, a[10], i, j, c, b[10];
double x[10], y[10];
for (c=1 ; scanf("%d", &n) != EOF && n ; c++) {
for (i=0 ; i<n ; i++) {
scanf("%lf%lf", x+i, y+i);
a[i] = i;
}
printf("**********************************************************\n");
printf("Network #%d\n", c);
double min = 10000000.0;
do {
double d = 0.0;
for (i=1 ; i<n ; i++)
d += dis(x[a[i-1]], y[a[i-1]], x[a[i]], y[a[i]]);
if (d < min) {
min = d;
memcpy(b, a, sizeof(int)*10);
}
} while (nextPermutation(a, n));
min = 0.0;
for (i=1 ; i<n ; i++) {
double d = dis(x[b[i-1]], y[b[i-1]], x[b[i]], y[b[i]]) + 16;
min += d;
printf("Cable requirement to connect (%.lf,%.lf) to (%.lf,%.lf) is %.2lf feet.\n",
x[b[i-1]], y[b[i-1]], x[b[i]], y[b[i]], d);
}
printf("Number of feet of cable required is %.2lf.\n", min);
}
}