和小哥哥一起刷洛谷(7) 图论之dijkistra算法
关于dijkstra
维基百科
戴克斯特拉算法(英语:Dijkstra's algorithm,又译迪杰斯特拉算法)由荷兰计算机科学家艾兹赫尔·戴克斯特拉在1956年提出。戴克斯特拉算法使用了广度优先搜索解决赋权有向图的单源最短路径问题。该算法存在很多变体;戴克斯特拉的原始版本找到两个顶点之间的最短路径,但是更常见的变体固定了一个顶点作为源节点然后找到该顶点到图中所有其它节点的最短路径,产生一个最短路径树。该算法常用于路由算法或者作为其他图算法的一个子模块。举例来说,如果图中的顶点表示城市,而边上的权重表示城市间开车行经的距离,该算法可以用来找到两个城市之间的最短路径。
该算法的输入包含了一个有权重的有向图 G,以及G中的一个来源顶点 S。我们以 V 表示 G 中所有顶点的集合。每一个图中的边,都是两个顶点所形成的有序元素对。(u, v) 表示从顶点 u 到 v 有路径相连。我们以 E 表示G中所有边的集合,而边的权重则由权重函数 w: E → [0, ∞] 定义。因此,w(u, v) 就是从顶点 u 到顶点 v 的非负权重(weight)。边的权重可以想像成两个顶点之间的距离。任两点间路径的权重,就是该路径上所有边的权重总和。已知 V 中有顶点 s 及 t,Dijkstra 算法可以找到 s 到 t 的最低权重路径(例如,最短路径)。这个算法也可以在一个图中,找到从一个顶点 s 到任何其他顶点的最短路径。
最初的戴克斯特拉算法不采用最小优先级队列,时间复杂度是O(|V|^2)其中|V|为图的顶点个数。通过斐波那契堆实现的戴克斯特拉算法时间复杂度是O(|E|+|V|\log |V|)(其中|E|是边数) 。对于不含负权的有向图,这是目前已知的最快的单源最短路径算法。
伪代码
声明优先队列&vis数组;
距离全设为无限;
起点入队;
起点设为零;
while(队列非空){
cur=最小项;
u=队列中最小的编号;
if(u去过)continue;
u标为访问过;
for(int i=0;i<u的出度;i++){
v=这个点的编号;
w=u到这个点的权值;
if(v访问过)continue;
if(u的最短路+w<v目前的最短路){
更新v的最短路;
v入队;
}
}
}
单源最短路径(标准版)
传说中专门卡spfa的一道题~
题目描述
给定一个 N 个点,M 条有向边的带非负权图,请你计算从 S 出发,到每个点的距离。
数据保证你能从 S 出发到任意点。
输入输出格式
输入格式:
第一行为三个正整数 N, M, S。 第二行起 M 行,每行三个非负整数 ui,vi,wi,表示从 ui 到 vi 有一条权值为 wi的边。
输出格式:
输出一行 N 个空格分隔的非负整数,表示 S 到每个点的距离。
样例:
输入:
4 6 1
1 2 2
2 3 2
2 4 1
1 3 5
3 4 3
1 4 4
输出:
0 2 4 3
思路
模版题还有思路?
代码
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<stack>
#include<queue>
#include<set>
#include<vector>
using namespace std;
struct Edge;
const int NR=100005;
int d[NR];
vector<Edge> adj[NR];
struct Node{//用于将优先队列从小到大排列的结构体
int id,dis;
Node(int id,int dis):id(id),dis(dis){}
bool operator < (const Node& b)const{//重载小于号,使得优先队列从小到大排序
return this->dis > b.dis;
}
};
struct Edge{//存储权值的结构体(可以用pair代替)
int v,w;
Edge(int v,int w):v(v),w(w){}
};
void dijkstra(int s){
priority_queue<Node> q;//优先队列
bool vis[NR];//是否去过
memset(vis,0,sizeof(vis));
memset(d,0x4f4f4f4f,sizeof(d));//距离全设为无限
d[s]=0;q.push(Node(s,0));//起点入队
while(!q.empty()){
Node cur=q.top();//取出队列中距离最短的
q.pop();
int u=cur.id;//u为当前点号
if(vis[u])continue;//若去过,则跳过
vis[u]=1;//标记已经去过
for(int i=0;i<adj[u].size();i++){
int v=adj[u][i].v;
int w=adj[u][i].w;
if(vis[v]) continue;//若去过,则跳过
if(d[u]+w < d[v]){//进行松弛
d[v]=d[u]+w;
q.push(Node(v,d[v]));
}
}
}
}
int main()
{
int n,m,start;
scanf("%d%d%d",&n,&m,&start);
for(int i=0;i<m;i++){
int st,en,w;
scanf("%d%d%d",&st,&en,&w);
adj[st].push_back(Edge(en,w));
}
dijkstra(start);
for(int i=1;i<=n;i++) printf("%d ",d[i]);
return 0;
}
和小哥哥一起刷洛谷(7) 图论之dijkistra算法的更多相关文章
- 和小哥哥一起刷洛谷(8) 图论之Floyd“算法”
关于floyd floyd是一种可以计算图中所有端点之间的最短的"算法",其伪代码如下: for(所有起点i) for(所有终点j) 如果i=j: i到j最短路设为0 如果i与j相 ...
- 和小哥哥一起刷洛谷(6) 图论之SPFA算法
关于\(spfa\) spfa伪代码: void spfa(s){ 最短路数组全部设为无限大; 队列 q; 起点s入队; s离s的距离设为零; while(队列非空){ 取出队首;弹出队首; for( ...
- 和小哥哥一起刷洛谷(5) 图论之深度优先搜索DFS
关于dfs dfs伪代码: void dfs(s){ for(int i=0;i<s的出度;i++){ if(used[i]为真) continue; used[i]=1; dfs(i); } ...
- 和小哥哥一起刷洛谷(4) 图论之广度优先搜索BFS
关于bfs: 你怎么会连这个都不知道!!!自己好好谷歌一下!!!(其实我也刚学) bfs伪代码: while(队列非空){ 取出队首元素u; 弹出队首元素; u染色为黑色; for(int i=0;i ...
- 莫队 [洛谷2709] 小B的询问[洛谷1903]【模板】分块/带修改莫队(数颜色)
莫队--------一个优雅的暴力 莫队是一个可以在O(n√n)内求出绝大部分无修改的离线的区间问题的答案(只要问题满足转移是O(1)的)即你已知区间[l,r]的解,能在O(1)的时间内求出[l-1, ...
- P4554 小明的游戏 (洛谷) 双端队列BFS
最近没有更新博客,全是因为英语,英语太难了QWQ 洛谷春令营的作业我也不会(我是弱鸡),随机跳了2个题,难度不高,还是讲讲吧,学学新算法也好(可以拿来水博客) 第一题就是这个小明的游戏 小明最近喜欢玩 ...
- 洛谷P1119-灾后重建-floyd算法
洛谷P1119-灾后重建 题目描述 给出\(B\)地区的村庄数NN,村庄编号从\(0\)到\(N-1\),和所有\(M\)条公路的长度,公路是双向的. 给出第\(i\)个村庄重建完成的时间\(t_i\ ...
- AC日记——小A的糖果 洛谷七月月赛
小A的糖果 思路: for循环贪心: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 100005 #defi ...
- AC日记——小B的询问 洛谷 P2709
小B的询问 思路: 水题: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 50005 #define ll ...
随机推荐
- 第二章:jQuery初探
一.引入jQuery XXXX.js文件 <script>标签 1.版本选择 当前jQuery有两个分支 1.x 支持ie6.7.8 jquery-1.11.2.js:未经过压缩,适合同学 ...
- springboot学习入门简易版六---springboot2.0整合全局捕获异常及log4j日志(12-13)
使用Aop实现 1创建异常请求 在原有项目基础上,jspController中创建一个可能发生异常的请求: /** * 全局捕获异常测试 * @param i * @return */ @Reques ...
- Delphi-RzDbgrid-绘制表格式设置某行颜色或者其他格式-以及隔行换色的属性
参考文章:https://www.cnblogs.com/OSKnown/p/8568740.html 在DbgridEh和原生的Dbgrid直接在DrawColumnCell事件中写重绘代码就好了, ...
- Linux常用时间函数
time()函数: NAME time - get time in seconds SYNOPSIS #include <time.h> time_t time(time_t *tloc) ...
- Systemweaver — 电子电气协同设计研发平台
当前电子电气系统随着功能安全.AutoSAR.车联网.智能驾驶等新要求,导致其复杂性.关联性日益上升.当前,传统基于文档的设计由于其低复用性.无关联性.无协同性等缺点,已经无法适应日益 ...
- php最快测试环境建立
win下待验证,但linux下真快. 不要nginx,不要php-fpm,就一个字,快! 1, 安装php yum install php 输出如下: Dependencies Resolved == ...
- 1219 Vue项目创建及基础
目录 vue项目 1. 项目创建 cmd创建 可视化创建 2. 项目启动 vue重新构建依赖 pycharm管理vue项目 3. 项目目录介绍 index.html index.js App.vue ...
- (java)selenium webdriver学习---实现简单的翻页,将页面内容的标题和标题链接取出
selenium webdriver学习---实现简单的翻页,将页面内容的标题和标题链接取出: 该情况适合能能循环page=1~n,并且每个网页随着循环可以打开的情况, 注意一定是自己拼接的url可以 ...
- navicat连接oracle报错:ORA-12737 Instant Client Light:unsupported server character set ZHS16GBK
今天使用Navicat连接Oracle数据库,报了下面的这个错误:“ORA-12737 Instant Client Light:unsupported server character set ZH ...
- Linux cut 用法
cut是一个选取命令,就是将一段数据经过分析,取出我们想要的.一般来说,选取信息通常是针对"行"来进行分析的,并不是整篇信息分析的. )其语法格式为:cut [-bn] [fil ...