#include <stdio.h>
#include <stdlib.h>
#define INF 65535 // 代价矩阵中的无限这里用一个较大的数表示
#define N 20
int cost[N][N] = { 0 };
int begin = 0; // 全局变量存储起始点
// removeData函数返回在数组path中去除一个元素elem后形成的新数组newPath
int *removeData(int path[], int n, int elem)
{
int *newPath = NULL;
if (n > 1)
newPath = (int *)malloc(sizeof(int) * (n - 1));
int j = 0;
for (int i = 0; i < n; i++)
{
if (path[i] != elem)
newPath[j++] = path[i];
}
return newPath;
}
int travel(int start, int path[], int n)
{
if (n == 0) // 递归出口,如果n == 0说明path数组中已经无元素,直接返回从出发点start回到起始点begin的路径长度
return cost[start][begin];
int min = INF, elem = 0, len = 0;
for (int i = 0; i < n; i++)
{
elem = path[i];
len = cost[start][elem] + travel(elem, removeData(path, n, elem), n - 1) ;
// len = 从出发点start到当前path[i]的路径长度 + 以path[i]为出发点经过去除了path[i]元素的path数组,最后返回出发点begin的路径长度
if (len < min)
{
min = len; // 选出其中最小的那个作为最后的结果
}
}
return min;
}
int tsp_dynamic(int n)
{
int *firstPath = (int *)malloc(sizeof(int) * n);
for (int i = 0; i < n; i++)
firstPath[i] = i;
int *path = removeData(firstPath, n, begin); // 使用的path数组应该是不包含一开始的出发点begin的
free(firstPath);
return travel(begin, path, n - 1);
}
/* 以下是贪心法解决tsp问题 */
int visited[N] = { 0 };
int tsp_greedy(int n)
{
int min = INF, minPath = 0, sum = 0;
visited[begin] = 1;
int k = begin;
for (int i = 0; i < n - 1; i++)
{
for (int j = 0; j < n; j++)
{
if (cost[k][j] < min && visited[j] == 0)
{
min = cost[k][j];
minPath = j;
}
}
sum = sum + min;
k = minPath;
min = INF;
visited[k] = 1;
}
sum = sum + cost[k][begin];
return sum;
}
/* 主函数 */
int main()
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
scanf("%d", &cost[i][j]); // 输入代价矩阵
printf("result = %d", tsp_dynamic(n)); // 输出结果
return 0;
}
本人水平一般,如有问题欢迎指正