7-2 旅行售货员 (10 分)(TSP问题思路加详解)

最后一个结点到源结点的距离 和 bestw进行比较更新,比其小就更新bestw,

否则,就跳过本轮循环,因为我们我们已经知道了其再往下走,也是不可能比bestw更小了

在这里插入图片描述

在这里插入图片描述

四:上码

===================================================================

/**

思路:

1.注意题目给出的完全有向图:

有向完全图是指概述图中各边都有方向,且每两个顶点之间都有两条方向相反的边连接的图。

2.通过分析据我们不难发现,每两个顶点间的距离是不一样的

3.写码思路:

<1>:本题解空间是排列树

<2>:我们在遍历树的时候我们采用的BFS,采用的数据结构是优先队列。

<3>:每次在选择扩展结点的时候,我们自定义的排序规则是将已有路径最小的先选择

<4>:选完扩展结点的时候,我们就要处理该扩展结点的邻接点,到达邻接点的距离小于bestw,我们就将该邻接点

统计到队列中

同时更新到达该结点路径程度,记录已经选择的路径顺序(x[i]),因为我们每次选择

的结点不同,所以我们记录的路径顺序也会有变化,那么就需要swap(x[t],x[j]),

这时候,我们就能得到正确的路径顺序。

<5>:当我们要遍历到叶节点的时候,这时候就要更新我们的bestw,将到达最后一个结点的距离加上

最后一个结点到源结点的距离 和 bestw进行比较更新,比其小就更新bestw,

否则,就跳过本轮循环,因为我们我们已经知道了其再往下走,也是不可能比bestw更小了

*/

#include<bits/stdc++.h>

using namespace std;

int INF=999999999;

const int N=100; //const 初始化

int maps[N][N]; //存储图

int n,m; //n表示顶点数,m表示边数

int bestw;

struct Node

{

int x[N]; //解向量,方便从1开始,记录路径

int cl; //表示当前已走过的路径长度

int id; //表示层数

};

//重写 优先队列当中排序方法 按每次路径最短的升序处理

bool operator<(const Node &a,const Node &b){

return a.cl>b.cl;

}

void bfs()

{

priority_queueq;

Node node;

node.cl = 0; // 0 表示当前已经的走的路径长度,2表示层数

node.id = 2;

//表示的是每个结点的序号,用于记录树当中路径

for(int i=1;i<=n;i++){

node.x[i]=i;

}

q.push(node);

while(!q.empty()){

//这个新结点的信息就是上方的node,其解向量为 1,2,3,4…而c = 0 id = 2;

Node newnode=q.top();

q.pop();

int t;

t = newnode.id;//当前层数

if(tn){//当n4的时候,其实是走了3个结点两个距离,所以还需要判断与最后一个结点

//的距离,以及最后一个结点和首节点的距离。

//如果两个结点中有一个的距离是无穷的那么,它的路径长度肯定不满足要求

if(maps[newnode.x[t-1]][newnode.x[n]] != INF

&& maps[newnode.x[n]][newnode.x[1]] != INF ){

//如果满足要求的话,那么就要判断已有的路径长度+到最后一个结点长度

//+最后一个结点到源结点的距离。

if(newnode.cl + maps[newnode.x[t-1]][newnode.x[n]]

  • maps[newnode.x[n]][newnode.x[1]] < bestw){

bestw = newnode.cl+maps[newnode.x[t-1]][newnode.x[n]]

  • maps[newnode.x[n]][newnode.x[1]];//更新bestw;

} else{//如果我们已经知道其最后的总路程是大于bestw的话,那就没有必要再统计其邻接点了

continue;

}

}else{//这里也是,如果我们已经知道其到达最后一个结点,或是最后一个结点到达首结点

//的距离是无穷的,那么我们就没必要再往下统计了

continue;

}

}

if(newnode.cl >= bestw) continue;//限界条件

//拿出队列当中的头节点,扩展其所有的分支

for(int j = t; j <= n; j++){//扩展所有分支

//这里是将当前的结点的临界点遍历,但是需要比较已有的路径

//长度跟当前的最优值,比其小才遍历,否则的话,再往下进行肯定是比最优值大的

//因为结点层数是比矩阵当中记录的行数多1,所以要减去。

if(newnode.cl + maps[newnode.x[t-1]][newnode.x[j]] < bestw){

int c = newnode.cl + maps[newnode.x[t-1]][newnode.x[j]];

//生成一个新的结点 且更新现在的路径长度和遍历的树的层数

Node node;

node.cl = c;

node.id = t+1;

//复制父节点的解向量

for(int i = 1; i <= n; i++)

node.x[i] = newnode.x[i];

//这个交换是为了 扩展结点可以在下一次的加入邻接点(活结点)的时候

//可以正确统计该活结点在矩阵当中的正确行数

swap(node.x[t],node.x[j]);

q.push(node);

}

}

}

}

int main(){

cin>>n;

for(int i=1;i<=n;i++){

for(int j = 1; j <= n; j++) {

int w;

cin >> w;

if(w == 0)

maps[i][j] = INF;

else

maps[i][j] = w;

}

}

bestw=INF;

bfs();

cout << bestw;

}

//3

//0 2 1

//1 0 2

//2 1 0

//3 6

//1 2 2

//1 3 1

//2 1 1

//2 3 2

//3 1 2

//3 2 1

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
610720988)]

[外链图片转存中…(img-ZM71Yfse-1715610720988)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

  • 30
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值