问题与解答

问题描述

求图中任意两个顶点之间的最短路径。

输入格式

输入数据第一行是一个正整数,表示图中的顶点个数n(顶点将分别按0,1,…,n-1进行编号)。之后的n行每行都包含n个整数,第i行第j个数表示顶点i-1和顶点j-1之间的边长,用10000来表示两个顶点之间无边。后面每行2个数字,表示一对待求最短路径的顶点,用-1 -1表示输入结束,-1 -1不求解。

输出格式

每对待求最短路径的顶点输出两行数据:第一行输出两个顶点间的最短路径长度,第二行输出最短路径,要按顺序输出顶点编号序列,顶点间用空格隔开。当两个顶点间没有路径时,只在一行上输出字符串“NO”。

样例输入

7

0 12 10000 10000 10000 10000 10000

12 0 10000 10000 3 10000 10000

10000 10000 0 10000 10000 21 11

10000 10000 10000 0 10000 10000 10000

10000 3 10000 10000 0 10000 8

10000 10000 21 10000 10000 0 10000

10000 10000 11 10000 8 10000 0

0 2

0 3

5 0

2 1

1 5

-1 -1

样例输出

34

0 1 4 6 2

NO

55

5 2 6 4 1 0

22

2 6 4 1

43

1 4 6 2 5

//最短路径
//求出所给两点之间的最短路径长度 并 输出最短路径
// Dijstra算法
#include<stdio.h>
#include<algorithm>
#include<stack>
using namespace std;
#define MaxN 100
#define INF 10000 //G[i][j] == INF表示i,j之间无边
int n; //顶点数
int G[MaxN][MaxN]; //邻接矩阵表示图
int d[MaxN]; //d[i]表示i到起点的距离
int path[MaxN]; //存储最短路径
bool Vis[MaxN] = {false}; //Vis[i]==true表示i已被访问
int Dijstra(int u, int v); //Dijstra算法
void PrintPath(int start, int end); //输出路径 int main(){
int start,end,Min_Length;
int i,j;
scanf("%d",&n); //输入顶点
for(i = 0; i < n; i++){ //输入图的邻接矩阵
for(j = 0; j < n; j++)
scanf("%d",&G[i][j]);
}
while(1){ //多点测试
scanf("%d%d",&start,&end);
if(start == -1 && end == -1) return 0; //结束程序
Min_Length = Dijstra(start, end); //调用Dijstra算法
if(Min_Length == -1) printf("No\n"); //打印结果
else{
printf("%d\n", Min_Length);
PrintPath(start,end);
}
}
} int Dijstra(int start, int end){
fill(d, d+n, INF); //初始化各数组
d[start] = 0;
fill(Vis,Vis+n,false);
path[start] = start; int i,u,v,Min;
for(i = 0; i < n; i++){ //循环n次
u = -1, Min = INF;
for(v = 0; v < n; v++){ //寻找未被访问的,距离起点距离最短的点
if(Vis[v] == false && d[v] < Min){
u = v;
Min = d[v];
}
}
if(u == -1) break; //图不连通,中断循环
Vis[u] = true; //标记已访问的点
for(v = 0; v < n; v++){ //以u为中介点对其未被访问的邻接点进行优化
if(G[u][v] != INF && Vis[v] == false
&& d[u] + G[u][v] < d[v])
{
d[v] = d[u] + G[u][v];
path[v] = u; //v的父(前驱)节点是u
}
}
}
if(d[end] == INF) return -1; //start与end不连通,不存在最短路径
else return d[end];//返回最短路径的长度
} void PrintPath(int start, int end){ //输出最短路径
stack<int> s;
int i = end;
s.push(end); //终点入栈
while(path[i] != i){
s.push(path[i]); //父(前驱)节点入栈
i = path[i];
}
while(!s.empty()){ //输出
printf("%d ",s.top());
s.pop();
}
printf("\n");
}

题后反思:调试记录

程序出错

忽略了Vis数组:

  • 与起点距离最短的点必须是“未被访问过的”
  • 而后要标记为“已访问”
  • 需要更新的邻接点必须是“未被访问过的”

在源代码基础上的改动

源代码:Dijstra算法

增加输入变量并改变有顶点不连通时的行为

  • 源代码输入起点start,计算start到其他所有顶点的最短距离,若有顶点不连通则函数返回-1
  • 改动后
    • 输入起点start 和 终点end, 若有顶点不连通则中断for循环
    • 根据d[end]是否==INF判断输出-1还是d[end](start与end的最小值)

增加path[]数组记录路径【父节点树/并查集】

  • path[v] = u表示 v的父节点是u
  • 沿path遍历父节点,入栈再出栈得到最短路径

<数据结构>XDOJ327.最短路径的更多相关文章

  1. 数据结构——图——最短路径D&F算法

    一.Dijkstra算法(贪心地求最短距离的算法) 在此算法中,我按照自己的理解去命名,理解起来会轻松一些. #define MAXSIZE 100 #define UNVISITED 0 #defi ...

  2. 数据结构学习笔记05图 (邻接矩阵 邻接表-->BFS DFS、最短路径)

    数据结构之图 图(Graph) 包含 一组顶点:通常用V (Vertex) 表示顶点集合 一组边:通常用E (Edge) 表示边的集合 边是顶点对:(v, w) ∈E ,其中v, w ∈ V 有向边& ...

  3. 数据结构 -- 图的最短路径 Java版

    作者版权所有,转载请注明出处,多谢.http://www.cnblogs.com/Henvealf/p/5574455.html 上一篇介绍了有关图的表示和遍历实现.数据结构 -- 简单图的实现与遍历 ...

  4. 算法与数据结构(六) 迪杰斯特拉算法的最短路径(Swift版)

    上篇博客我们详细的介绍了两种经典的最小生成树的算法,本篇博客我们就来详细的讲一下最短路径的经典算法----迪杰斯特拉算法.首先我们先聊一下什么是最短路径,这个还是比较好理解的.比如我要从北京到济南,而 ...

  5. 数据结构与算法--最短路径之Bellman算法、SPFA算法

    数据结构与算法--最短路径之Bellman算法.SPFA算法 除了Floyd算法,另外一个使用广泛且可以处理负权边的是Bellman-Ford算法. Bellman-Ford算法 假设某个图有V个顶点 ...

  6. 数据结构与算法--最短路径之Floyd算法

    数据结构与算法--最短路径之Floyd算法 我们知道Dijkstra算法只能解决单源最短路径问题,且要求边上的权重都是非负的.有没有办法解决任意起点到任意顶点的最短路径问题呢?如果用Dijkstra算 ...

  7. 数据结构与算法--最短路径之Dijkstra算法

    数据结构与算法--最短路径之Dijkstra算法 加权图中,我们很可能关心这样一个问题:从一个顶点到另一个顶点成本最小的路径.比如从成都到北京,途中还有好多城市,如何规划路线,能使总路程最小:或者我们 ...

  8. 数据结构实习 Problem H 迷宫的最短路径

    数据结构实习 Problem H 迷宫的最短路径 题目描述 设计一个算法找一条从迷宫入口到出口的最短路径. 输入 迷宫的行和列m n 迷宫的布局 输出 最短路径 样例输入 6 8 0 1 1 1 0 ...

  9. 数据结构实验之图论七:驴友计划 ( 最短路径 Dijkstra 算法 )

    数据结构实验之图论七:驴友计划 Time Limit: 1000 ms           Memory Limit: 65536 KiB Submit Statistic Discuss Probl ...

随机推荐

  1. flink01--------1.flink简介 2.flink安装 3. flink提交任务的2种方式 4. 4flink的快速入门 5.source 6 常用算子(keyBy,max/min,maxBy/minBy,connect,union,split+select)

    1. flink简介 1.1 什么是flink Apache Flink是一个分布式大数据处理引擎,可以对有限数据流(如离线数据)和无限流数据及逆行有状态计算(不太懂).可以部署在各种集群环境,对各种 ...

  2. vue SCSS

        C:\eclipse\wks\vue\esql-ui>node -v v12.18.1 C:\eclipse\wks\vue\esql-ui>npm -v 6.14.5 直接修改p ...

  3. zabbix之模板制作(memcache redis)

    #:找一台主机安装redis和memcached(记得安装zabbix-agent) root@ubuntu:~# apt install redis root@ubuntu:~# apt insta ...

  4. Linux:awk与cut命令的区别

    结论:awk 以空格为分割域时,是以单个或多个连续的空格为分隔符的;cut则是以单个空格作为分隔符.

  5. 【C/C++】n皇后问题/全排列/递归/回溯/算法笔记4.3

    按常规,先说一下我自己的理解. 递归中的return常用来作为递归终止的条件,但是对于返回数值的情况,要搞明白它是怎么返回的.递归的方式就是自己调用自己,而在有返回值的函数中,上一层的函数还没执行完就 ...

  6. 关于python中的随机种子——random_state

    random_state是一个随机种子,是在任意带有随机性的类或函数里作为参数来控制随机模式.当random_state取某一个值时,也就确定了一种规则. random_state可以用于很多函数,我 ...

  7. Jenkins视图管理

    目录 一.简介 二.视图维护 创建视图 将项目加入视图中 三.状态图标变绿 四.看板 一.简介 在现在的编程中,公司往往采用的是模块化的编程方式,也就是说将一个项目拆分成许多模块,每个小项目组往往只负 ...

  8. pwnable_start (内联汇编)

    第一次写内联汇编的题目,以前见师傅们在exp中写汇编,感觉很厉害,今天碰到了,也记录一下. 下载附件发现是32位程序,什么保护都没开,ida看一下伪代码. 可以说是很简洁了,调用了一个write和re ...

  9. 论文翻译:2021_MetricGAN+: An Improved Version of MetricGAN for Speech Enhancement

    论文地址:MetricGAN+:用于语音增强的 MetricGAN 的改进版本 论文代码:https://github.com/JasonSWFu/MetricGAN 引用格式:Fu S W, Yu ...

  10. LuoguP5238 整数校验器 题解

    Content 给定两个整数 \(l,r\),再给定 \(T\) 个整数,请判断对于每个整数 \(x\),是否满足以下要求: \(x\in[l,r]\). \(x\) 格式合法. 数据范围:\(-2^ ...