#define _CRT_SECURE_NO_WARNINGS
/*
7 10
0 1 5
0 2 2
1 2 4
1 3 2
2 3 6
2 4 10
3 5 1
4 5 3
4 6 5
5 6 9
6
*/
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
using namespace std; const int maxn = + ;
const int INF = ;
int cost[maxn][maxn]; //表示边e=(u,v)的权值 (不存在这条边时设为INF)
int d[maxn]; //顶点出发的最短距离
bool used[maxn]; //已经使用过的图
int V, E;
void init();
void dijkstra(int s);
void input(); void init()
{
for (int i = ; i < V; i++) {
for (int j = ; j < V; j++) {
if (i == j) {
cost[i][j] = ;
}
else {
cost[i][j] = INF;
}
}
}
} void dijkstra(int s)
{
fill(d, d + V, INF);
fill(used, used + V, false);
d[s] = ; while (true) {
int v = -;
//从尚未使用过的顶点中选择一个距离最小的顶点
for (int u = ; u < V; u++) {
if (!used[u] && (v == - || d[u] < d[v])) {
v = u;
}
}
if (v == -) break; //已经没有尚未使用的点了
used[v] = true; //标志v已访问 for (int u = ; u < V; u++) {
d[u] = min(d[u], d[v] + cost[u][v]);
}
}
} void input()
{
int s, t, ct;
for (int i = ; i < E; i++)
{
cin >> s >> t >> ct;
cost[s][t] = cost[t][s] = ct;
}
} int main()
{
cin >> V >> E; //输入顶点数和边数
init(); //必须要初始化
input(); //输入临接的边和权值
dijkstra(); //设置起点
int ov;
cin >> ov; //输入终点
cout << d[ov] << endl;
return ;
}

//解法二:

需要优化的是数值的插入(更新)和取出最小值两个操作,因此使用堆就可以了。把每个顶点当前的最短距离用堆维护,在更新最短距离时,把对应的元素往根的方向移动以满足堆的性质。而每次从堆中取出的最小值就是下一次要使用的顶点。这样堆中元素共有O(|V|)个。更新和取出数值的操作有O(|E|)次,因此整个算法复杂度是O(|E|log|V|)。

下面是使用STL的priority_queue的实现。在每次更新时往堆里插入当前最短距离和顶点的值对。插入的次数是O(|E|)次,因此元素也是O(|E|)个。当取的最小值不是最短距离的话,就丢弃这个值。

 #define _CRT_SECURE_NO_WARNINGS
/*
7 10
0 1 5
0 2 2
1 2 4
1 3 2
2 3 6
2 4 10
3 5 1
4 5 3
4 6 5
5 6 9
6
*/
#include <iostream>
#include <vector>
#include <utility>
#include <queue>
#include <functional>
#include <algorithm>
#include <cstdio>
using namespace std; const int maxn = + ;
const int INF = ;
struct edge
{
int to, cost;
};
typedef pair<int, int> P; //first是最短距离,second是顶点的编号
int V, E;
vector<edge> G[maxn];
int d[maxn];
//void init();
void input(); void dijkstra(int s)
{
//通过指定greater<P>参数,堆按照first从小到大的顺序取出值
priority_queue<P, vector<P>, greater<P> > que;
fill(d, d + V, INF);
d[s] = ;
que.push(P(, s)); while (!que.empty()) {
P p = que.top(); que.pop();
int v = p.second;
if (d[v] < p.first) continue;
for (int i = ; i < G[v].size(); i++) {
edge e = G[v][i];
if (d[e.to] > d[v] + e.cost) {
d[e.to] = d[v] + e.cost;
que.push(P(d[e.to], e.to));
}
}
}
} //void init()
//{
//} void input()
{
int s, t, ct;
edge tmp;
for (int i = ; i < E; i++) {
cin >> s >> t >> ct;
tmp.to = t; tmp.cost = ct;
G[s].push_back(tmp);
//无向图,反向也需要连接
tmp.to = s; tmp.cost = ct;
G[t].push_back(tmp);
}
} int main()
{
cin >> V >> E;
//init();
input();
dijkstra();
int ov;
cin >> ov;
cout << d[ov] << endl;
return ;
}

单源最短路径问题(dijkstra算法 及其 优化算法(优先队列实现))的更多相关文章

  1. 单源最短路径(dijkstra算法)php实现

    做一个医学项目,当中在病例评分时会用到单源最短路径的算法.单源最短路径的dijkstra算法的思路例如以下: 如果存在一条从i到j的最短路径(Vi.....Vk,Vj),Vk是Vj前面的一顶点.那么( ...

  2. 单源最短路径:Dijkstra算法(堆优化)

    前言:趁着对Dijkstra还有点印象,赶快写一篇笔记. 注意:本文章面向已有Dijkstra算法基础的童鞋. 简介 单源最短路径,在我的理解里就是求从一个源点(起点)到其它点的最短路径的长度. 当然 ...

  3. 0016:单源最短路径(dijkstra算法)

    题目链接:https://www.luogu.com.cn/problem/P4779 题目描述:给定一个 n 个点,m 条有向边的带非负权图,计算从 s 出发,到每个点的距离. 这道题就是一个单源最 ...

  4. 【算法导论】单源最短路径之Dijkstra算法

    Dijkstra算法解决了有向图上带正权值的单源最短路径问题,其运行时间要比Bellman-Ford算法低,但适用范围比Bellman-Ford算法窄. 迪杰斯特拉提出的按路径长度递增次序来产生源点到 ...

  5. 单源最短路径问题-Dijkstra算法

    同样是层序遍历,在每次迭代中挑出最小的设置为已知 ===================================== 2017年9月18日10:00:03 dijkstra并不是完全的层序遍历 ...

  6. 单源最短路径(3):SPFA 算法

    SPFA(Shortest Path Faster Algorithm)算法,是西南交通大学段凡丁于 1994 年发表的,其在 Bellman-ford 算法的基础上加上一个队列优化,减少了冗余的松弛 ...

  7. 【模板】单源最短路径(Dijkstra)/洛谷P4779

    题目链接 https://www.luogu.com.cn/problem/P4779 题目大意 给定一个 \(n\) 个点 \(m\) 条边有向图,每个点有一个非负权值,求从 \(s\) 点出发,到 ...

  8. [模板]单源最短路径(Dijkstra)

    如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度. 主要还是再打一遍最短路,这种算法我用的不多... #include<bits/stdc++.h> using namesp ...

  9. Dijkstra算法解决单源最短路径

    单源最短路径问题:给定一个带权有向图 G = (V, E), 其中每条边的权是一个实数.另外,还给定 V 中的一个顶点,称为源.现在要计算从源到其他所有各顶点的最短路径长度.这里的长度是指路上各边权之 ...

随机推荐

  1. Activiti的BPMN演示工具

    场景是这样的:产品经理不懂技术,又不想安装Java以及Eclipse(需要安装Activiti BPMN Designer的插件). 这两天解决.bpmn的解析(BPMNParser)时顺带找到一个顺 ...

  2. SQLSERVER最简单的同名数据库恢复过程.

    一. 冷备份恢复 1. net stop mssqlserver # 如果是安装的默认数据库实例 关闭 sqlserver的数据库 2. copy sqlserver的数据文件 主要是mdf 数据文件 ...

  3. sleep、yield、wait、join的区别(阿里面试)

    1.  Thread.sleep(long) 和Thread.yield()都是Thread类的静态方法,在调用的时候都是Thread.sleep(long)/Thread.yield()的方式进行调 ...

  4. BZOJ2008 JSOI2010连通数(floyd+bitset)

    一直不明白为什么要用floyd求传递闭包,直接搜不是更快嘛……不过其实可以用bitset优化,方法也比较显然.bitset是真的神奇啊,好多01状态且转移相似的东西都可以用这个优化一下. #inclu ...

  5. Ubuntu 安装 hadoop

    安装完Linux后,我们继续(VMWare 安装 Linux  http://blog.csdn.net/hanjun0612/article/details/55095955) 这里我们开始学习安装 ...

  6. MT【70】图论的一些基本概念例题介绍

    此讲是纯粹竞赛,联赛二试题难度.仅供学有余力的学生看看.

  7. Oracle drop table 和 truncate table对grant授权的影响

    [oracle@crl ~]$ rlwrap sqlplus / as sysdba SQL*Plus: Release 11.2.0.4.0 Production on Tue May 16 14: ...

  8. Hdoj 1008.Elevator 题解

    Problem Description The highest building in our city has only one elevator. A request list is made u ...

  9. install kubernetes cluster k8s集群安装

    一,安装docker-ce 17.031,下载rpm包 Wget -P /tmp https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/ ...

  10. AAD Service Principal获取azure user list (Microsoft Graph API)

    本段代码是个通用性很强的sample code,不仅能够操作AAD本身,也能通过Azure Service Principal的授权来访问和控制Azure的订阅资源.(Azure某种程度上能看成是两个 ...