看注释
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <iomanip>
using namespace std;
#define N 4
#define MAX 0x3f3f3f3f
int dp[N][1 << (N - 1)]; // dp数组
int path[N][1 << (N - 1)]; // 路径
// 课本例题 N=4
int distances[N][N] = {{MAX, 3, 6, 7},
{5, MAX, 2, 3},
{6, 4, MAX, 2},
{3, 7, 5, MAX}}; // 距离
int removeCity(int j, int k)
{ // 从j二进制表示的城市集合中去除k号城市(k位设为0)
return j - (1 << (k - 1));
}
int TSP()
{
if (N == 1)
return 0; // 只有一个结点
for (int i = 1; i < N; i++)
{
dp[i][0] = distances[i][0]; // 初始化所有城市到0号城市的距离
}
for (int j = 1; j < (1 << (N - 1)); j++)//集合<j> -> 0
{
for (int i = 1; i < N; i++)
{
if ((j >> (i - 1)) % 2 == 0)
{ // i号城市不在j二进制形式表示的城市集合里
// cout << "i " << i << "j " << j << endl;
int min = MAX;
int next_city = i;
for (int k = 1; k < N; k++)
{
if ((j >> (k - 1)) % 2 != 0)
{ // k号城市在j二进制形式表示的城市集合里
int temp = distances[i][k] + dp[k][removeCity(j, k)]; // 表示把k号城市从j城市集合中去除
if (temp < min)
{
min = temp;
next_city = k;
}
}
}
dp[i][j] = min;
path[i][j] = next_city;
}
}
}
//{0,<S>},0经过<j>到0
int min = MAX;
int next_city = 0;
int j = (1 << (N - 1)) - 1; // 代表除0号城市外的所有城市组成的集合
for (int k = 1; k < N; k++)
{
int temp = distances[0][k] + dp[k][removeCity(j, k)];
if (temp < min)
{
min = temp;
next_city = k;
}
}
dp[0][j] = min;
path[0][j] = next_city;
return dp[0][j];
}
void printPath(int i, int j)
{ // 打印路线 i为出发城市编号 j为剩下城市组成的集合
if (j != 0)
{
cout << i << " -> ";
int next_city = path[i][j];
printPath(next_city, removeCity(j, next_city));
}
else
{
cout << i << " -> " << 0;
}
}
int main()
{
// 纵轴为0,1,2...表示城市编号
// 横轴为000,001,010,...第x位为1,代表该集合里面有x号城市
// 随机初始化distances[N][N]
// srand((unsigned int)time(NULL));
// for (int i = 0; i < N; i++)
// {
// for (int j = i; j < N; j++)
// {
// if (i == j)
// distances[i][j] = MAX;
// else
// {
// int temp = rand();
// while (temp == 0)
// {
// temp = rand();
// }
// distances[i][j] = distances[j][i] = temp;
// }
// }
// }
// 打印代价矩阵
cout << "结点数为:[" << N << "]" << endl;
cout << "代价矩阵为:" << endl;
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
if (distances[i][j] == MAX)
cout << setw(5) << "INF"
<< " ";
else
cout << setw(5) << distances[i][j] << " ";
}
cout << endl;
}
cout << "最短距离为:" << TSP() << endl;
cout << "旅行路线为:";
printPath(0, (1 << (N - 1)) - 1);
system("pause");
return 0;
}