#include "stdio.h"
#include "string.h"
#define MAX 10
#define NoEdge 0
int n; //城市个数
int a[5][5]; //保存路径,邻接矩阵
int x[MAX]; //路径序列
int bestx[MAX]; //最短路径序列
int cc = 0; //当前所走路径长度
int bestc = NoEdge; //最短路径
void swap(int &a, int &b)
{
int temp = a;
a = b;
b = temp;
}
void backtrack(int i)
{
if(i==n) //叶节点的父节点
{
/*最后1个城市与前一城市相连、与第1个城市相连,组成1个满足条件的回路
比较当前回路与以前最佳回路,看当前回路是否更优
*/
if(a[x[n-1]][x[n]]!=NoEdge && a[x[n]][x[1]]!=NoEdge && cc+a[x[n-1]][x[n]]+a[x[n]][x[1]]<bestc || bestc==NoEdge)
{
int j;
for(j=1; j<=n; j++)
bestx[j] = x[j]; //更新最短路径序列
bestc = cc+a[x[n-1]][x[n]]+a[x[n]][x[1]]; //更新最短路径长度
}
}
else //当前结点位于排列树的第i-1层
{
int j;
for(j=i; j<=n; j++) //当前的选择,去往哪个城市
{
/*向当前部分路径加入新城市x[j]后, x[j]与x[i-1]相连,
且扩展后的部分路径<1, x[2],…, x[i-1], x[j], …, ?>的成本小于当前最优回路的长度
*/
if(a[x[i-1]][x[i]]!=NoEdge && cc+a[x[i-1]][x[i]]<bestc || bestc==NoEdge)
{
swap(x[i], x[j]); //加入第i个城市
cc += a[x[i-1]][x[i]]; //更新扩展后的路径的代价
backtrack(i+1); //搜索下一层
cc -= a[x[i-1]][x[i]]; //搜索失败,回溯,为搜索x[i]的另一个取值x[j+1]准备
swap(x[i], x[j]);
}
}
}
}
void travel(int a1[5][5], int n1)
{
n = n1;
int i, j;
for(i=1; i<=n; i++)
for(j=1; j<=n; j++)
a[i][j] = a1[i][j];
for(i=1; i<=n; i++)
x[i] = i;
backtrack(2);
}
int main()
{
int n1 = 4;
int a1[5][5]={
{0, 0, 0, 0, 0},
{0, 0, 30, 6, 4},
{0, 30, 0, 5, 10},
{0, 6, 5, 0, 20},
{0, 4, 10, 20, 0},
};
travel(a1, n1);
printf("城市个数:%d\n", n);
int i, j;
printf("邻接矩阵为:\n");
for(i=1; i<=n; i++)
{
for(j=1; j<=n; j++)
printf("%d\t", a[i][j]);
printf("\n");
}
printf("最短回路为:\n");
for(i=1; i<=n; i++)
printf("%d-->", bestx[i]);
printf("%d", bestx[1]);
printf("\n");
printf("路径长度为:%d\n", bestc);
return 0;
}