【做练习】附近编号最大的城市(有源最短路Dijkstra算法)

这是一篇关于使用Dijkstra算法解决一个编程练习题的博客。题目要求找出距离城市1不超过K的所有城市中编号最大的城市。博主分析了问题,指出这是一个非负权有向图的有源最短路问题,并提供了Dijkstra算法的实现,代码简洁并使用了C++ 11的lambda表达式。
摘要由CSDN通过智能技术生成

这是在openjudge百练上看到的一道练习题,我看到通过率有点儿低,以为会有点儿难度。实际上是个送分题。

题目

描述

有N(不大于10)座城市,编号为1至N,已知任意两个城市间直接距离(不超过1000的非负整数)。求距离(直接或间接)城市1不超过K(K为小于100的正整数)的所有城市中编号最大的是哪座。

输入

第一行输入一个整数n
第二行输入一个整数K
之后n行,每行n个整数,描述了城市间距离的邻接矩阵,其中第i行第j个表示城市i到城市j的距离。相邻整数用空格分开。

输出

距离不超过K的城市的最大编号

样例

Input:

3
3
0 1 4
1 0 3
4 3 0

Output:

2

分析

经典的非负权有向图的有源最短路,使用Dijkstra算法求解。
简单地说,Dijkstra算法,就是:

  1. 将所有的节点分为两组,一组是已知最短路的(记为A),一组是未知最短路的(记为B)。最初所有节点都在B中。
  2. 记录一个距离数组D[N],表示从源src到其它所有点的“已计算的最短距离”。如果一个点 i 在组A中,那么D[i]就表示了最短路的距离。如果点 i 在组B当中,D[i]表示的距离是待计算优化的。
  3. 初始化时,D[源] = 0,D[其它节点]=无穷大
  4. 循环:每次从B组找到一个 i ∈ B   m i n i m i z e   D [ i ] i \in B\ minimize\ D[i] iB minimize D[i],将 i i i放到A组去。并对所有和 i i i有邻接的节点 j j j,令 D [ j ] ← m
当然可以!以下是使用Dijkstra算法求解最短路径的MATLAB代码示例: ```matlab function [dist, path] = dijkstra(adjMatrix, startNode) numNodes = size(adjMatrix, 1); % 初始化距离数组 dist = inf(1, numNodes); dist(startNode) = 0; % 初始化路径数组 path = cell(1, numNodes); path{startNode} = startNode; % 创建一个标记数组,用于记录节点是否已被访问 visited = false(1, numNodes); % 运行Dijkstra算法 for i = 1:numNodes-1 % 找到当前距离最小的节点 [~, currentNode] = min(dist .* ~visited); visited(currentNode) = true; % 更新与当前节点相邻的节点的距离 neighbors = find(adjMatrix(currentNode, :)); for j = neighbors if ~visited(j) && dist(currentNode) + adjMatrix(currentNode, j) < dist(j) dist(j) = dist(currentNode) + adjMatrix(currentNode, j); path{j} = [path{currentNode}, j]; end end end end ``` 使用示例: ```matlab % 定义一个邻接矩阵表示图的连接关系 adjMatrix = [ 0 3 0 4 0; 3 0 5 0 0; 0 5 0 2 6; 4 0 2 0 1; 0 0 6 1 0 ]; % 调用Dijkstra算法求解最短路径 [startNode, endNode] = deal(1, 5); [dist, path] = dijkstra(adjMatrix, startNode); % 输出结果 disp(['从节点', num2str(startNode), '到节点', num2str(endNode), '的最短距离为:', num2str(dist(endNode))]); disp(['最短路径为:', num2str(path{endNode})]); ``` 这段代码实现了Dijkstra算法的逻辑,并且可以根据输入的邻接矩阵和起始节点,求解出最短路径的距离和路径。希望能对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值