旅行商问题(tsp问题)就是一个经销商从n个城市中的某一城市出发,不重复的走完其余的n-1个城市并回原出发点,求所有可能路径单中走出路径长度最短的一条。
本题假设旅行商从第一个城市出发。
解法:dfs+回溯
#include <iostream>
using namespace std;
#define NUM 100
int n;//图G的顶点数
int m;//图G的边数
int a[NUM][NUM];//图G的邻接矩阵
int x[NUM] = {0}; //当前解
int bestx[NUM];//最优解
int cc = 0; //当前费用
int bestc = 0; //当前最优值
int NoEdge = -1; //无边标记
int Visited[100];//访问标志
int num = 0;
int FirstArc(int t)
{
for(int i = 1; i <= m; i++)
if(a[t][i] != NoEdge)
return i;
return 0;
}
int NextArc(int t, int w)
{
for(int p = w + 1; p <= m; p++)
if(a[t][p] != NoEdge)
return p;
return 0;
}
void dfs(int t)
{
int l, i;
Visited[t] = 1;
if(num == m && a[t][1] != NoEdge)
{
if(cc + a[t][1] < bestc)
{
bestc = cc + a[t][1];
for(int s = 0; s < m; s++)
bestx[s] = x[s];
}
}
else
{
for(i = FirstArc(t); i != 0; i = NextArc(t, i))
if(!Visited[i] && a[t][i] != NoEdge)
if(cc + a[t][i] < bestc) //剪枝
{
x[num++] = i;
cc += a[t][i];
dfs(i);
cc -= a[t][i];
Visited[i] = 0;
num--;
}
}
}
void tsp(int t)
{
for(int i = 1; i <= m; i++)
Visited[i] = 0;
//保存第一个节点
x[num++] = t;
Visited[t] = 1;
for(int q = FirstArc(t); q != 0; q = NextArc(t, q))
if(a[t][q] != NoEdge && !Visited[q])
{
x[num++] = q;
cc += a[t][q];
dfs(q);
cc -= a[t][q]; //回溯
Visited[q] = 0;
num--;
}
}
int main()
{
int s, e, t;
scanf("%d%d", &m, &n);
//初始化邻接矩阵
for(int i = 1; i <= m; i++)
for(int j = 1; j <= m; j++)
a[i][j] = NoEdge; //表示两个节点不相连
for(int i = 1; i <= n; i++)
{
scanf("%d%d%d", &s, &e, &t);
a[s][e] = t;
a[e][s] = t;
}
//初始化变量
bestc = 1000;
tsp(1);
for(int i = 0; i < m; i++)
printf("%d ", bestx[i]);
printf("\nbestc=%d\n", bestc);
return 0;
}
/*
1 2 20
1 4 4
1 3 6
2 3 5
2 4 10
3 4 15
*/