最短路径wt_q.push( ( node ){0, s} );是什么意思-程序员宅基地

技术标签: 算法  Powered by 金山文档  

1.弗洛伊德(Floyd )

用来求解赋权图中每对顶点间的最短距离,Floyd算法是经典的动态规划算法,基本思想是递推产生一个矩阵序列A1,A2,…,Ak,…,An(图有n个节点),Ak=(ak(i,j))nxn。其中矩阵Ak第i行第j列表示从顶点vi到顶点vj的路径上经过的顶点序号不大于k的最短路径长度。

电车

题目描述

在一个神奇的小镇上有着一个特别的电车网络,它由一些路口和轨道组成,每个路口都连接着若干个轨道,每个轨道都通向一个路口(不排除有的观光轨道转一圈后返回路口的可能)。在每个路口,都有一个开关决定着出去的轨道,每个开关都有一个默认的状态,每辆电车行驶到路口之后,只能从开关所指向的轨道出去,如果电车司机想走另一个轨道,他就必须下车切换开关的状态。

为了行驶向目标地点,电车司机不得不经常下车来切换开关,于是,他们想请你写一个程序,计算一辆从路口 A A A 到路口 B B B 最少需要下车切换几次开关。

输入格式

第一行有 3 3 3 个整数 N , A , B N,A,B N,A,B( 2 ≤ N ≤ 100 , 1 ≤ A , B ≤ N 2 \leq N \leq 100, 1 \leq A,B \leq N 2≤N≤100,1≤A,B≤N),分别表示路口的数量,和电车的起点,终点。

接下来有 N N N 行,每行的开头有一个数字 K i K_i Ki​( 0 ≤ K i ≤ N − 1 0 \leq K_i \leq N-1 0≤Ki​≤N−1),表示这个路口与 K i K_i Ki​ 条轨道相连,接下来有 K i K_i Ki​ 个数字表示每条轨道所通向的路口,开关默认指向第一个数字表示的轨道。

输出格式

输出文件只有一个数字,表示从 A A A 到 B B B 所需的最少的切换开关次数,若无法从 A A A 前往 B B B,输出 − 1 -1 −1。

样例 #1

样例输入 #1

3 2 1

2 2 3

2 3 1

2 1 2

1

2

3

4

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
int n, s, e, m, x, f[1001][1001];
void floy()
{
for (int k = 1; k <= n; k++)
{
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
if (!(i == j || i == k || j == k))
{
f[i][j] = min(f[i][k] + f[k][j], f[i][j]);
}
}
}
}
}
int main()
{
memset(f, INF, sizeof(f));
cin>>n>>s>>e;
for (int i = 1; i <= n; i++)
{
f[i][i] = 0;
}
for (int i = 1; i <= n; i++)
{
cin >> m;
for (int j = 1; j <= m; j++)
{
cin >> x;
if (j == 1)
{
f[i][x] = 0;
}
else
{
f[i][x] = 1;
}
}
}
floy();
if (f[s][e] == INF)
{
cout << "-1";
}
else
{
cout<<f[s][e];
}
return 0;
}

样例输出 #1

0

1

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

通过中间点k求得是从i —> j近还是从i —> k —> j 近,从而求得点a到点b的最短路径(a和b都是随机点)可以把一个路口看作一张图中的一个点,轨道是图中的边(注意:这是有向图),每一条边的权值就是这个边所联通的点是否需要按按钮(需要按按钮就是1,不需要按按钮就是0)然后就用求最短路径的算法算出最少需要按的开关数。

2.迪杰斯特拉(dijkstra)

在已知图的邻接矩阵的条件下,通过遍历已知图的所有路径,用 dis[i] 数组来记录到i点的最短路径,然后在循环中不断判断更替。首先,将所有点的集合分为俩部分,一边是已经遍历过的,另外一边是没有遍历过的,分别用mark[i]=1、mark[i]=0来表示。层层扩散,实时比较和更新最短路径。

以起始点为中心向外层层扩展,直到扩展到终点为止。由for循环可知,其时间复杂度是O(n^2)。

【模板】单源最短路径(弱化版)

题目背景

本题测试数据为随机数据,在考试中可能会出现构造数据让SPFA不通过,如有需要请移步 P4779。

题目描述

如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度。

输入格式

第一行包含三个整数 n , m , s n,m,s n,m,s,分别表示点的个数、有向边的个数、出发点的编号。

接下来 m m m 行每行包含三个整数 u , v , w u,v,w u,v,w,表示一条 u → v u \to v u→v 的,长度为 w w w 的边。

输出格式

输出一行 n n n 个整数,第 i i i 个表示 s s s 到第 i i i 个点的最短路径,若不能到达则输出 2 31 − 1 2^{31}-1 231−1。

样例 #1

样例输入 #1

4 6 1

1 2 2

2 3 2

2 4 1

1 3 5

3 4 3

1 4 4

1

2

3

4

5

6

7

样例输出 #1

0 2 4 3

1

提示

【数据范围】

对于 20 % 20\% 20% 的数据: 1 ≤ n ≤ 5 1\le n \le 5 1≤n≤5, 1 ≤ m ≤ 15 1\le m \le 15 1≤m≤15;

对于 40 % 40\% 40% 的数据: 1 ≤ n ≤ 100 1\le n \le 100 1≤n≤100, 1 ≤ m ≤ 1 0 4 1\le m \le 10^4 1≤m≤104;

对于 70 % 70\% 70% 的数据: 1 ≤ n ≤ 1000 1\le n \le 1000 1≤n≤1000, 1 ≤ m ≤ 1 0 5 1\le m \le 10^5 1≤m≤105;

对于 100 % 100\% 100% 的数据: 1 ≤ n ≤ 1 0 4 1 \le n \le 10^4 1≤n≤104, 1 ≤ m ≤ 5 × 1 0 5 1\le m \le 5\times 10^5 1≤m≤5×105, 1 ≤ u , v ≤ n 1\le u,v\le n 1≤u,v≤n, w ≥ 0 w\ge 0 w≥0, ∑ w < 2 31 \sum w< 2^{31} ∑w<231,保证数据随机。

Update 2022/07/29:两个点之间可能有多条边,敬请注意。

对于真正 100 % 100\% 100% 的数据,请移步 P4779。请注意,该题与本题数据范围略有不同。

样例说明:

图片1到3和1到4的文字位置调换

#include<bits/stdc++.h>
using namespace std;
#define maxn 10005
#define maxm 500005
#define INF  1234567890
inline int read()
{
    int x=0,k=1; char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')k=-1;c=getchar();}
    while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return x*k;
}
struct Edge
{
    int u,v,w,next;
}e[maxm];
int head[maxn],cnt,n,m,s,vis[maxn],dis[maxn];
struct node
{
    int w,now;
    inline bool operator <(const node &x)const
    //重载运算符把最小的元素放在堆顶(大根堆)
    {
        return w>x.w;//这里注意符号要为'>'
    }
};
priority_queue<node>q;
//优先队列,其实这里一般使用一个pair,但为了方便理解所以用的结构体
inline void add(int u,int v,int w)
{
    e[++cnt].u=u;
    //这句话对于此题不需要,但在缩点之类的问题还是有用的
    e[cnt].v=v;
    e[cnt].w=w;
    e[cnt].next=head[u];
    //存储该点的下一条边
    head[u]=cnt;
    //更新目前该点的最后一条边(就是这一条边)
}
//链式前向星加边
void dijkstra()
{
    for(int i=1;i<=n;i++)
    {
        dis[i]=INF;
    }
    dis[s]=0;
    //赋初值
    q.push((node){0,s});
    while(!q.empty())
    //堆为空即为所有点都更新
    {
        node x=q.top();
        q.pop();
        int u=x.now;
        //记录堆顶(堆内最小的边)并将其弹出
        if(vis[u]) continue; 
        //没有遍历过才需要遍历
        vis[u]=1;
        for(int i=head[u];i;i=e[i].next)
        //搜索堆顶所有连边
        {
            int v=e[i].v;
            if(dis[v]>dis[u]+e[i].w)
            {
            dis[v]=dis[u]+e[i].w;
            //松弛操作
            q.push((node){dis[v],v});
            //把新遍历到的点加入堆中
            }
        }
    }
}
int main()
{
    n=read(),m=read(),s=read();
    for(int i=1,x,y,z;i<=m;i++)
    {
        x=read(),y=read(),z=read();
        add(x,y,z);
    }
    dijkstra();
    for(int i=1;i<=n;i++)
    {
        printf("%d ",dis[i]);
    }
    return 0;
}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

首先用数组dis记录起点到每个结点的最短路径,再用一个数组保存已经找到最短路径的点

然后,从dis数组选择最小值,则该值就是源点s到该值对应的顶点的最短路径,并且把该点记为已经找到最短路

此时完成一个顶点,再看这个点能否到达其它点(记为v),将dis[v]的值进行更新

不断重复上述动作,将所有的点都更新到最短路径

迪杰斯特拉算法:

迪杰斯特拉算法是一种用于求解最短路径的算法,它可以在一个有向图中求出从一个顶点到其他所有顶点的最短路径。它的基本思想是:从源点出发,每次选择距离源点最近的顶点,更新源点到其他顶点的最短路径。

弗洛伊德算法:

弗洛伊德算法是一种用于求解最短路径的算法,它可以在一个有向图中求出从一个顶点到其他所有顶点的最短路径。它的基本思想是:从源点出发,每次选择距离源点最近的顶点,更新源点到其他顶点的最短路径。它的优点是可以处理负权边,但是它的时间复杂度是O(n^3)。

Bellman-Ford算法:

Bellman-Ford算法是一种用于求解最短路径的算法,它可以在一个有向图中求出从一个顶点到其他所有顶点的最短路径。它的基本思想是:从源点出发,每次选择距离源点最近的顶点,更新源点到其他顶点的最短路径。它的优点是可以处理负权边,而且它的时间复杂度是O(mn),其中m是边的数量,n是顶点的数量。

典型最短路径算法,用于计算一个节点到其他节点的最短路径。

基本原理:逐遍的对图中每一个边去迭代计算起始点到其余各点的最短路径,执行N-1遍,最终得到起始点到其余各点的最短路径。(N为连通图结点数)

SPFA算法:

SPFA算法是一种用于求解最短路径的算法,它可以在一个有向图中求出从一个顶点到其他所有顶点的最短路径。它的基本思想是:从源点出发,每次选择距离源点最近的顶点,更新源点到其他顶点的最短路径。它的优点是可以处理负权边,而且它的时间复杂度是O(mn),其中m是边的数量,n是顶点的数量。它的缺点是它可能会出现负环,所以在使用SPFA算法之前,需要先检测图中是否存在负环。

spfa跑的比较kuai

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/HuiHuangDDFS/article/details/129048785

智能推荐

c# 调用c++ lib静态库_c#调用lib-程序员宅基地

文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib

deepin/ubuntu安装苹方字体-程序员宅基地

文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang

html表单常见操作汇总_html表单的处理程序有那些-程序员宅基地

文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些

PHP设置谷歌验证器(Google Authenticator)实现操作二步验证_php otp 验证器-程序员宅基地

文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器

【Python】matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距-程序员宅基地

文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距

docker — 容器存储_docker 保存容器-程序员宅基地

文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器

随便推点

网络拓扑结构_网络拓扑csdn-程序员宅基地

文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn

JS重写Date函数,兼容IOS系统_date.prototype 将所有 ios-程序员宅基地

文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios

如何将EXCEL表导入plsql数据库中-程序员宅基地

文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql

Git常用命令速查手册-程序员宅基地

文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...

分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120-程序员宅基地

文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120

【C++缺省函数】 空类默认产生的6个类成员函数_空类默认产生哪些类成员函数-程序员宅基地

文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数

推荐文章

热门文章

相关标签