#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
#define maxn 1000
#define NoEdge 0x3f3f3f
int m;//路径数
int n;//顶点数
int road[maxn][maxn]= {NoEdge}; //路径的邻接矩阵
int x[maxn];//当前解
int bestx[maxn];//最优解
int l;//当前路径长度
int bestl=NoEdge;//最优路径长度
void BackTrack(int i)
{
if(i==n)//到达叶子节点
{
if(road[x[i-1]][x[i]]!=NoEdge&&road[x[1]][x[i]]!=NoEdge&&l+road[x[i-1]][x[i]]+road[1][x[i]]<bestl)
{//n-1到n之间1到n之间存在路径并且改回路长度比最优解短,则记录当前解为最优解
for(int j=1; j<=n; j++)
{
bestx[j]=x[j];
}
bestl=l+road[x[n-1]][x[n]]+road[1][x[n]];
}
}
else//未到达叶子节点
{
for(int j=i; j<=n; j++)//没走过的路径遍历一遍
{
//i-1到j之间有路径并且当前路径长度加上i-1到j的距离比当前最短路径短
if(road[x[i-1]][x[j]]!=NoEdge&&l+road[x[i-1]][x[j]]<bestl)
{
swap(x[i],x[j]);//将j交换到i的位置
l+=road[x[i-1]][x[i]];//记录当前路径长度
BackTrack(i+1);//继续下一层
l-=road[x[i-1]][x[i]];//返回上一层
swap(x[i],x[j]);//将路径位置调回原位置,保证搜索顺序与解空间树一致(可省略)
}
}
}
}
/*测试用例
4 6
1 2 30
1 3 6
1 4 4
2 3 5
2 4 10
3 4 20
*/
int main()
{
cout<<"输入城市个数及路径条数:"<<endl;
cin>>n>>m;
for(int i=1; i<=n; i++)
{
x[i]=i;
}
int a,b,c;
printf("输入存在路径的两点及路径长度:\n");
for(int i=0; i<m; i++)
{
cin>>a>>b>>c;
road[a][b]=c;
road[b][a]=c;
}
BackTrack(2);
cout<<endl<<"最优路径为:"<<endl;
for(int i=1; i<=n; i++)
cout<<bestx[i]<<" -> ";
cout<<"1"<<endl;
cout<<endl<<"最优路径长度为:";
cout<<endl<<bestl<<endl;
}
旅行售货员问题(回溯法求解)
最新推荐文章于 2023-01-06 12:33:41 发布