题目描述
已知N个城市之间的相互距离,现有一推销员必须遍访这N个城市,并且每个城市只能访问一次,最后又必须返回出发城市。如何安排他对这些城市的访问次序,可使其旅行路线的总长度最短?
用图论的术语来说,假设有一个图G = ( V , E ) ,其中V是顶点集合,E 是边集合,设D = [ d(i,j) ]是由顶点i和顶点j之间的距离所组成的距离矩阵,旅行商问题就是求出一条通过所有顶点且每个顶点只通过一次的具有最短距离的回路。
输入
输入数据由若干行组成;第一行为问题的规模N即城市的数目,剩下的N行为一个N*N的距离矩阵。
输出
请输出周游路线的最短距离。
样例输入复制
4 0 30 6 4 30 0 5 10 6 5 0 20 4 10 20 0
样例输出复制
25
贪心暴力解法:
#include<iostream>
#include <cstring>
using namespace std;
const int INF = 9999;
const int maxn = 100 + 5;
int n;
int dis[maxn][maxn];
bool book[maxn];
int x;
int Min=INF;
void DFS(int i, int k, int pathlen)
{//i表示当前节点,k表示走过了k个点,pathlen表示经过的路径和
if (k == n)
{
Min =min(pathlen + dis[i][x],Min);
return;
}
int minlen = INF, u;//minlen表示当前节点到下一个节点的最短路径,u表示下一个节点
for (int j = 1; j <= n; j++)
{
if (!book[j] && minlen > dis[i][j])//取与所有点的连边中最小的边
{
u = j;
book[j] = true;
DFS(u, k + 1, pathlen + dis[i][j]);
book[j] = false;
}
}
}
int main()
{
cin >> n;
if(n != 1)
{
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
cin >> dis[i][j];
}
}
for(x = 1; x <= n; x++)
{//x表示起点
memset(book, false, sizeof(book));
book[x] = true;
DFS(x, 1, 0);//递归出所有路径
}
cout << Min << endl;
}
else cout << 0 << endl;
return 0;
}