算法学习:关于最短路径的计算(深度优先搜索)

本文通过一个地图最短路径问题介绍如何利用深度优先搜索算法寻找起点到终点的最小代价。在搜索过程中,使用标记数组记录访问状态,不断回溯尝试不同路径,直到找到最小代价路径。详细解释了算法思路并强调了回溯过程中清除访问标记的重要性。
摘要由CSDN通过智能技术生成

第一次写文章,写得不够好的地方还望大家多多谅解,感谢指正

今天做了一条题目,只有一张地图(如图在这里插入图片描述),输入任意起点和终点,求从起点到终点的最小代价。
题目图
另外,从一个点(i)到另一个点(j)的代价计算方法为:All=Weight[i]+maps[i][j]+Weight[j],其中Weight[i]表示点i的权值,maps[i][j]表示点i到点j的代价,Weight[j]表示点j的权值。

这道题其实比较简单,采用的算法的主要思想就是深度优先搜索。我的做法就是首先给每个点标上序号,主要是为了方便程序设计,如图所示,然后建立一个二维数组maps[][],表示点i到点j之间的代价,再创立一个String数组。用来存放每个点的名字,主要用于输出,创立一个boolean类型的数组flag[],表示第i个点是否有被访问过,创立一个int类型的数组weight[],表示每个点的权值。

这道题的主要解决思想就是在这个图中,先创立一个int型变量Min=10000,记录从起点到终点的最小代价,创立两个数组Array[]和MinArray[],分别记录访问过的点和代价最小路径所经过的点。
从一个点(假设为A)出发,flag[A]=true,访问一个临近的点(假设为B),把B设置为已访问(flag[B]=true),All=All+Weight[A]+maps[A][B]+Weight[B],把B存进Array[]中;然后再访问B的一个临近点(假设为C),把C设置为以访问(flag[C]=true),All=All+Weight[B]+maps[B][C]+Weight[C],把C存进Array[]中,一直这样访问下去,直到访问到某个点(假设为F),flag[F]=true,All=All+Weight[上一个点]+maps[上一个点][C]+Weight[C],把F存进Array[]中,判断这个点F是不是我们要访问的终点。

如果是的话,将从A点到F点的代价与Min比较,如过小于Min,则把从A到F的所经过的点存进MinArray[]中,然后返回上一层(这里要注意:返回上一层的时候记得要把访问完的点flag设置为false,表示该点未被访问,一定要注意,否则从其它路径出发的话是没法访问到这个点的,一定要切记),访问F的上一个点(假设为E),再从E开始访问与E相邻的除了F以外的所有点,寻找其它可以到达F的路径,直到与E的相邻所有路径都被访问过后,再返回E的上一层(假设为D),再从D开始访问与D相邻的除了E以外的所有点,寻找其它可以到达F的路径,一直类推,直到把从起点到终点的所有路径都走过一遍。

如果不是的话,并且点F已经没有与其相邻的点,则直接返回上一层,flag[F]=false,再按照上面的思路继续下去。
不难看出这里用到的思想其实就是一种回溯的想法。再次提醒,每返回上一层的时候都要把本次访问的点的flag设置为false,否则下次无法访问。

下面贴上代码,可能写得有点乱,结合解题思路慢慢看应该不难懂:

import java.util.Scanner;

public class Homework {
   

	/**
	 * @param args
	 */
	public static int maps[][]={
   {
   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, //该数组用来表示每个点之间的距离值,0表示两个点之间无法直接到达,第一行和第一列不使用,方便下面的处理
			{
   0,0,71,0,0,0,0,0,151,0,0,0,0,0,0,0,0,0,0,0,0},             //1,表示点Oradea
			{
   0,71,0,75,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},               //2,表示点Zerind
			{
   0,0,75,0,118,0,0,0,140,0,0,0,0,0,0,0,0,0,0,0,0,0},    //3,表示点Arad
			{
   0,0,0,118,0,111,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},          //4,表示点Timisoara
			{
   0,0,0
  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值