讲了半天好像也许maybe听懂了一点,先写下来233

先整理整理怎么存(开始绕)

最简单的是邻接矩阵存,但是开到10000*10000就MLE了,所以我们用链式前向星存(据说是叫这个名字吧)

这是个什么鬼玩意呢?

我们在记录时,以输入的顺序记录。

我们记录一条边,就记下它的终点(to),权值(就是边长)(dis),以及和这条边的起点相同,编号稍微小一点的边的编号(next)(开始绕)

这里我们记录当前每个点的所有出边(就是起点是这个点的边)中编号最大的那一条边(因为上面的next是编号稍微小的边)

当然也可以依据自己的习惯存储边

先上段代码

int head[nmax],n,m,s;//head[i] 是 以 点 i 为 起 点 , 所 有 出 边 中 编 号 最 大 的 一 个
priority_queue<pair<int,int> > q;
void add(int fr,int _to,int _dis)
{    cnt++;eage[cnt].to=_to;eage[cnt].dis=_dis;eage[cnt].next=head[fr];//fr 为 from 的 简 写 , 这 里 的 以 点 i 为 起 点 的 边 多 了 一 条,//所 以 上 一 个 以 点 i 为 起 点 的 编 号 最 大 的 边 就 是 这 里 的 以 i 为 起 点 编 号 最 大 的 边 的 上 一 条 边 head[fr]=cnt; //更 新 head[i]
}Edge [50001];
const int inf=2147483647;
int main()
{  scanf("%d%d%d",&n,&m,&o_node);dis[o_node]=0;for(int i=1;i<=m;i++){int from,to,dis;cin>>from>>to>>dis;add(from,to,dis);}

这一坨是存图

拿张图举个例子

假设我们输入边的数据如下(三个数n,m,s,n为起点,m为终点,s为边长)

1 2 2

2 3 2

1 3 5

2 4 1

3 4 2

1 4 4

那代码中的存储如下

Edge[1].to=2,Edge[1].dis=2,Edge[1].next=0,head[1]=1(这里指没有上一条边),head[1]=1(这里head[i]记录的是以i为起点,当前最大编号出边的编号)

Edge[2].to=3,Edge[2].dis=2,Edge[2].next=0,head[2]=2

Edge[3].to=3,Edge[3].dis=5,Edge[3].next=1,head[1]=3

.....................................

讲完存图,再来说这个算法是怎么实现的

要求最短路径,这里有点类似贪心。

首先选择一个距离起点最近的直达点b,记录当前点与b的距离,再由b进行相同的扩展,来更新起点与其它点的距离

这样更新了一圈后就是最短距离,

再举个栗子

没错还是刚才那张图,这里标出了每条边的权值

按照dijkstra算法,我们首先找到距离①最近的直达点②,由②更新出①到④的最短路为3,①到③的最短路为4,

那么程序怎么实现呢?

看注释吧

(代码from gh,注释自己加的)

#include <iostream>
#include <cstdio>
#include <queue>using namespace std;
const int INF = 2147483647;
struct edge
{int to, dis_, next;
} Edge[500001];
struct node
{int to, dis;inline friend bool operator<(const node &a, const node &b){return a.dis < b.dis;//构造函数,将优先队列按照权值从小到大排序}
};
int head[500001], dis[10001];
bool vst[10001];
int nodenum, edgenum, origin_node, cnt = 1;
priority_queue<node> q;//优先队列inline void add_edge(int from, int to, int value)
{Edge[cnt].to = to;Edge[cnt].dis_ = value;Edge[cnt].next = head[from];head[from] = cnt++;
}inline void dijkstra()
{for (register int i = 1; i < origin_node; i++){dis[i] = INF;//全部初始化为一个很大的数}dis[origin_node]=0;for (register int i = origin_node + 1; i <= nodenum; i++){dis[i] = INF;}q.push((node){origin_node, 0});while (!q.empty())//队不空(这里是当广搜来做的){int x = q.top().to;q.pop();if (vst[x])//如果访问过,就跳过continue;vst[x] = 1;for (register int i = head[x]; i; i = Edge[i].next)//从以x为起点的最后一条边开始,一直遍历完这个点的所有边{dis[Edge[i].to] = min(dis[Edge[i].to], dis[x] + Edge[i].dis_);//比较原来的大小和以x点为中转后的大小(取小的)q.push((node){Edge[i].to, -dis[Edge[i].to]});//入队}}
}template <typename T_>
inline T_ getnum()
{T_ res = 0;bool flag = false;char ch = getchar();while (!isdigit(ch)){flag = flag ? flag : ch == '-';ch = getchar();}while (isdigit(ch)){res = (res << 3) + (res << 1) + ch - '0';ch = getchar();}return flag?-res:res;
}
template<typename T_>
inline void putnum(T_ num)
{if (num<0){putchar('-');num=-num;}if (num>9)putnum(num/10);putchar('0'+num%10);
}int main()
{nodenum = getnum<int>(), dgenum  = getnum<int>(),origin_node = getnum<int>();for (register int i = 1; i <= edgenum; i++){register int f, t, v;f = getnum<int>(), t = getnum<int>(), v = getnum<int>();add_edge(f, t, v);}dijkstra();for (register int i=1;i<=nodenum;putchar(' '),i++){putnum<int>(dis[i]);}return 0;
}

顺便附上一道dijkstra的题

一本通之城市路:

这个好像就是个模板哈

(代码from题解)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
#include<cstdlib>
#include<queue>
#include<set>
#include<vector>
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define N 3001
#define MOD 123
#define E 1e-6
using namespace std;
struct node{int pre;int next;int w;
}a[N*10];
int n,m;
int cnt;
int head[N],vis[N],f[N];
void add(int x,int y,int w)
{cnt++;a[cnt].pre=y;a[cnt].next=head[x];a[cnt].w=w;head[x]=cnt;cnt++;a[cnt].pre=x;a[cnt].next=head[y];a[cnt].w=w;head[y]=cnt;
}//存图int main()
{cin>>n>>m;for(int i=1;i<=m;i++){int x,y,w;cin>>x>>y>>w;add(x,y,w);}memset(f,INF,sizeof(f));f[1]=0;vis[1]=1;int x=head[1];//手动模拟第一次出队while(x!=0){int y=a[x].pre;if(f[y]>a[x].w)f[y]=a[x].w;x=a[x].next;}int cnt=0;while(cnt<n)//遍历所有的点{cnt++;int k;int minn=INF;for(int i=1;i<=n;i++)if(vis[i]==0&&f[i]<minn){minn=f[i];k=i;}//先把能赋值的距离赋值上vis[k]=1;int x=head[k];//手动模拟for循环while(x!=0)//这里木有队列,所以要while循环一次处理完{int y=a[x].pre;int w=a[x].w;if(vis[y]==0&&f[y]>f[k]+w)f[y]=f[k]+w;x=a[x].next;}}if(f[n]==INF)cout<<"-1"<<endl;elsecout<<f[n]<<endl;return 0;
}

转载于:https://www.cnblogs.com/lcez56jsy/p/10732560.html

Dijkstra求最短路径例题相关推荐

  1. dijkstra标号法表格_标号法求最短路径例题详解.ppt

    标号法求最短路径例题详解 r * 最短路径 带权图G=, 其中w:E?R. ?e?E, w(e)称作e的权. e=(vi,vj), 记w(e)=wij . 若vi,vj不 相邻, 记wij =?. 设 ...

  2. 55、【图】Dijkstra求最短路径(单源最短路径+边权重为正数)(C/C++版)

    算法介绍 Dijkstra算法是基于贪心思想,用于实现只含有正权边的单源最短路径问题,单源路径是从一个固定起始点出发到其余各点的路径. 算法过程: 首先,获取起始点到其余点的距离,然后从起始点出发,每 ...

  3. 用标号法求最短路径matlab,标号法求最短路径例题详解重点.ppt

    r * 最短路径 带权图G=, 其中w:E?R. ?e?E, w(e)称作e的权. e=(vi,vj), 记w(e)=wij . 若vi,vj不 相邻, 记wij =?. 设L是G中的一条路径, L的 ...

  4. 用标号法求最短路径matlab,标号法求最短路径例题分析.ppt

    r * 最短路径 带权图G=, 其中w:E?R. ?e?E, w(e)称作e的权. e=(vi,vj), 记w(e)=wij . 若vi,vj不 相邻, 记wij =?. 设L是G中的一条路径, L的 ...

  5. python基于广度优先(BFS)的迪杰斯特拉(Dijkstra)算法 求最短路径

    python深度优先与广度优先的遍历算法区别 首先要理解搜索步,一个完整的搜索步包括两个处理: a) 获得当前位置上,有几条路可供选择 b) 根据选择策略,选择其中一条路,并走到下个位置 广度优先:就 ...

  6. CSP认证201609-4 交通规划[C++题解]:最短路径树、dijkstra求单源最短路、递推思想

    题目分析 来源:acwing 分析: 这题是最短路树.保持原图中所有点到根结点的最短距离不变,然后在原图中选择一些边,使所有点连通的最短路是多长. 最短路径树,是一种使用最短路径算法生成的数据结构树. ...

  7. Java图结构-模拟校园地图-迪杰斯特拉(Dijkstra)算法求最短路径 #谭子

    目录目录 一.前言 二.模拟校园地图描述 三.分析题目及相关绘图 四.代码部分 1.GraphNode类 2.Menu类(管理文字) 3.Attraction类 4.AttractionGraph类( ...

  8. 迪杰斯特拉算法(Dijkstra)求最短路径Python

    迪杰斯塔拉(Dijkstra)算法求最短路径 序 关于Dijkstra Dijkstra算法讲解 Dijkstra算法的弊端 第一步:进行初始化 第二步:主程序开始 又是初始化 核心的核心[^5] 最 ...

  9. 图算法——求最短路径(Dijkstra算法)

    目录 一.什么是最短路径 二.迪杰斯特拉(Dijkstra)算法 三.应用Dijkstra算法 (1) Dijkstra算法函数分析 求图的最短路径在实际生活中有许多应用,比如说在你在一个景区的某个景 ...

最新文章

  1. 正在通过iTunes Store 进行鉴定
  2. 8个我希望早点意识到的学生思维
  3. C++拷贝构造函数调用时机
  4. 5年 Python 功力,总结了 10 个开发技巧
  5. redis下并发问题解决方案
  6. C# 子类实例化基类 基类使用不了子类的方法_C#高级编程面试考题
  7. 拿到大厂Offer了!
  8. 【软件工程】复利计算器--结对编程
  9. Thinkpad SL400安装黑苹果10.8.4全纪录
  10. 性能计数器驱动_Linux CPU性能优化方法
  11. 2020,我的年终总结(附优惠券)
  12. 使用media player和foobar的DLAN服务
  13. 计算机电源安装,手把手教你正确安装主机电源
  14. ysoserial exploit/JRMPListener原理剖析
  15. iPad远程控制windows主机及内网穿透原理
  16. MFC 按钮控件添加图片
  17. 权威SSL证书的CA机构有哪些
  18. Python的5大就业方向,薪资诱人前景好
  19. 利用WebBrower封装的自己的浏览器MyIE源代码
  20. AutoCAD 2019 怎么设置经典模式(经典界面)?

热门文章

  1. linux 会不会受到永恒之蓝漏洞,永恒之蓝漏洞复现(ms17-010)
  2. python设置http代理_python中设置HTTP代理的方法
  3. SQL Sever 数据完整性
  4. Python入门--字典元素的遍历for-in
  5. router优点 vue_Vue 出场率99%的面试题
  6. 操作系统—内存的连续分配管理方式
  7. 腾讯校园招聘笔试 2019-8-17 第四题
  8. Pikachu实验过程1(函数报错的信息)
  9. bzoj 1655: [Usaco2006 Jan] Dollar Dayz 奶牛商店(高精度完全背包)
  10. self.modules() 和 self.children()的区别