递归枚举应用,递归枚举所有可能出现的序列,在递归里面取最优的一组就行了,注意当当前的总长已经超过最小的总长的时候递归就可以回溯了。
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <float.h>
struct pos
{
double x;
double y;
};
struct pos all_pos[10];
struct pos serial[10];
struct pos min_serial[10];
unsigned char visited[10];
double min_dis;
double get_dis(const struct pos &p1, const struct pos &p2)
{
return sqrt(pow(p1.x-p2.x,2.0)+pow(p1.y-p2.y,2.0));
}
void dfs(int len, int cur, double cur_dis)
{
int i, j;
double dis;
if(cur == len+1)
{
if(cur_dis < min_dis)
{
min_dis = cur_dis;
for(i=1; i<=len; i++)
{
min_serial[i].x = serial[i].x;
min_serial[i].y = serial[i].y;
}
}
}
if(cur == 1)
{
for(i=1; i<=len; i++)
{
serial[cur].x = all_pos[i].x;
serial[cur].y = all_pos[i].y;
visited[i] = 1;
dfs(len, cur+1, cur_dis);
visited[i] = 0;
}
}
else
{
for(i=1; i<=len; i++)
{
if(!visited[i])
{
serial[cur].x = all_pos[i].x;
serial[cur].y = all_pos[i].y;
visited[i] = 1;
dis = get_dis(serial[cur], serial[cur-1]);
if(cur_dis+dis<min_dis)
dfs(len, cur+1, cur_dis+dis);
visited[i] = 0;
}
}
}
}
void func(int n)
{
int i;
memset((void*)visited, 0, sizeof(unsigned char)*10);
min_dis = DBL_MAX;
dfs(n, 1, 0.0);
for(i=2; i<=n; i++)
{
printf
(
"Cable requirement to connect (%.0lf,%.0lf) to (%.0lf,%.0lf) is %.2lf feet.\n",
min_serial[i-1].x,
min_serial[i-1].y,
min_serial[i].x,
min_serial[i].y,
get_dis(min_serial[i-1], min_serial[i])+16
);
}
printf("Number of feet of cable required is %.2lf.\n", min_dis+16*(n-1));
}
int main(void)
{
int n;
int i;
int case_count;
//freopen("input.dat", "r", stdin);
case_count = 0;
while(scanf("%d", &n))
{
if(!n)
break;
for(i=1; i<=n; i++)
scanf("%lf %lf", &(all_pos[i].x), &(all_pos[i].y));
case_count ++;
printf("**********************************************************\n");
printf("Network #%d\n", case_count);
func(n);
}
return 0;
}