单源最短路Dijstra算法

Dijstra算法是寻找从某一顶点i出发到大其他顶点的最短路径。Distra算法的思想与Prim算法很像,它收录顶点的规则是按照路径长度递增的顺序收录的。设v0是源顶点,我们要寻找从v0出发到其他任意一点的最短路径。设已经求解的顶点(已经找到从v0出发到达该顶点最短路径的顶点)组成的集合是S={v0,v1,...vk};在收录下一个顶点v的时候要么是(v0,v),要么是(v0,vj,v);如果是后者,则一定有vj∈S,这一点很容易用反正法证明。Dijstra算法的时间复杂度是O(V^2),若是稀疏图改用邻接表存储,使用最小堆时间复杂度是O(ElogV).具体代码如下(这里假设图是连通的),有相应的解释:

 1 #include<iostream>
 2 using namespace std;
 3 #define MAX_SIZE 100
 4 #define MAX_NUMBER INT_MAX/2
 5 struct Graph {
 6   int V, E;
 7   int w[MAX_SIZE][MAX_SIZE];
 8 };
 9 bool visit[MAX_SIZE];
10 int dis[MAX_SIZE];
11 int parent[MAX_SIZE];
12 void Dijstra(Graph G, int i);     //顶点i为出发点到其他点最短距离
13 void PrintPath(int j);
14 int main() {
15     int i, j,w,k;
16     Graph G;
17     for (i = 0; i < MAX_SIZE; i++)
18     for (j = 0; j < MAX_SIZE; j++)
19         G.w[i][j] = (i == j ? 0 :MAX_NUMBER);        //对角线设置为0,其它设置为无穷
20     cin >> G.V >> G.E;
21     for (k=0; k< G.E; k++) {
22         cin >> i >> j >> w;
23         G.w[i][j] = G.w[j][i]=w;
24     }
25     Dijstra( G, 3);
26     for (i = 0; i < G.V; i++)
27         printf("%d  %d\n",i, dis[i]);
28     PrintPath(6);           //打印顶点6的路径
29     return 0;
30 }
31 void Dijstra(Graph G, int i) {
32     int k, j,pos,min;
33     memset(visit, 0, sizeof(visit));     //初始化
34     for (j = 0; j < G.V; j++)
35         dis[j] = MAX_NUMBER;               //首先将距离都设置为无穷大
36     j = i;
37     dis[j] = 0;                 //到自身距离为0
38     parent[j] = -1;            //i是父节点
39     visit[j] = 1;             //首先将顶点i本身收录
40     for (i = 1; i < G.V; i++) {
41         for (k = 0; k < G.V; k++) {     //更新上次收录的顶点j对其他顶点的影响
42             if (!visit[k] && dis[k]>=dis[j] + G.w[j][k]) {//这里G.w[j][k]在之前初始化不要设置为INT_MAX,否则dis[j]+G.w[j][k]
43                 //可能会超过int的范围。
44                 dis[k] = dis[j] + G.w[j][k];
45                 parent[k] = j;
46             }
47         }
48         pos = j, min =MAX_NUMBER;
49         for (k = 0; k < G.V; k++) {
50             if (!visit[k] && min>dis[k]) {
51                 pos = k;
52                 min = dis[k];
53             }
54         }
55         j = pos;
56         visit[j] = 1;  //将j收录
57     }
58 }
59 void PrintPath(int j) {
60     if (j== -1)
61         return;
62     PrintPath(parent[j]);
63     printf("%d  ", j);
64 }
时间: 2024-12-26 08:47:00

单源最短路Dijstra算法的相关文章

[hiho 23]单源最短路-Dijstra算法

题目描述 维护一个集合,集合中的元素与点u的最短距离已经确定,求出集合内元素所能到达的点到点u的距离,取最短的距离对应的点加入集合直到集合包含点v. 每次更新距离只与新加入集合的点有关. #include <stdio.h> #include <string.h> #include <algorithm> #define N 1005 unsigned w[N][N]; int main(){ memset(w, -1, sizeof(w)); int n, m, u,

单源最短路 Bellman-Ford算法

单源最短路问题是固定一个起点s,求它到所有点的最短路的问题. Bellman-Ford算法可以用于边权为负的情况而不像Dijkstra只适用于边权为正的情况(有负圈返回错误),但是其效率比较低. 记从起点s出发到顶点i的最短距离为的d[i] 那么 d[i] = min(d[j]+(j->i)|其中j->i属于E) 如果给定的图是DAG 那么可以用拓扑序给顶点编号,并利用这一条递推公式计算出d(DP). 如果图中有圈,就无法依赖这样的顺序进行计算.这种情况初始d[s]=0 d[i]=INF 再不

图论-单源最短路-SPFA算法

有关概念: 最短路问题:若在图中的每一条边都有对应的权值,求从一点到另一点之间权值和最小的路径 SPFA算法的功能是求固定起点到图中其余各点的的最短路(单源最短路径) 约定:图中不存在负权环,用邻接表存储有向图,di存放从起点到结点i的最短路,q为队列,保存待处理节点 思路: 首先指定起点入队,取当前队头结点u,沿每一条与u相连的边向外扩展,对该边所指向的结点v松弛(比较当前dv与当前du加此边长,更新最短路值dv,以及最短路径prev)如果v不在队列中且更新了最短路值,v进队,直至队列中没有元

单源最短路Dijkstra算法——matlab实现

迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径. 它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止. 基本思想 通过Dijkstra计算图G中的最短路径时,需要指定起点s(即从顶点s开始计算). 此外,引进两个集合S和U.S的作用是记录已求出最短路径的顶点(以及相应的最短路径长度),而U则是记录还未求出最短路径的顶点(以及该顶点到起点s的距离). 初始时,S中只有起点s:U中是除s之外的顶点,并且U中顶点的路径是"起点s

单源最短路——Dijkstara算法

算法基本思想:每次找到离源点最近的一个顶点,然后以该顶点为中心进行扩展,最终得到源点到其余所有点的最短路径. 1.将所有的顶点分为两个部分:已知最短路程的顶点集合P和未知最短路径的顶点集合Q 2.设置源点s到自己的最短路径为0,若存在有源点能够直接到达的顶点i则吧dis[i]设置为e[s][i].同时把所有其它不能直接到达的顶点的最短路径设置为∞ 3.在集合Q的所有顶点中选择一个离源点s最近的顶点u即dis[u]最小,加入到集合P.并考察所有以点u为起点地边,对每条边进行松弛操作. 4.重复第三

单源最短路-dijkstra算法(未优化)

1 bool used[maxn]; 2 int g[maxn][maxn]; // 边未联系的填充为INF 3 int d[maxn]; 4 void dijkstra(int s){ 5 memset(g,false,sizeof(g)); 6 memset(d,INF,sizeof(d)); 7 d[s] = 0; 8 while(1){ 9 int v = -1; 10 for(int u = 0; u<v; u++){ 11 if(!used[u] && (v == -1|

Dijkstra算法 --- 单源最短路

Dijkstra算法适用于边权值为正的情况,可用于计算正权图上的单元最短路. 其伪代码如下: 设d[v0] = 0, 其他d[i] = INF 循环n次{ 在所有未标号的结点中,选取d值最小的结点x 给结点x加上永久标号 对于从x出发的所有边,执行松弛操作. } //松弛操作的伪代码如下: RELAX(u,v,w) if(u.d + w(u,v) < v.d){ v.d = w.d + w(u,v); pre[v] = u; } Dijkstra算法代码: /* Dijkstra 单源最短路算法

【裸单源最短路:Dijkstra算法两种版本】hdu 1874 畅通工程续

Source : hdu 1874 畅通工程续 http://acm.hdu.edu.cn/showproblem.php?pid=1874 Problem Description 某省自从实行了很多年的畅通工程计划后,终于修建了很多路.不过路多了也不好,每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案要比另一些方案行走的距离要短很多.这让行人很困扰. 现在,已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离. Input 本题目包含多组数据,请处理到文件结束.

再看最短路算法 1 —— 单源最短路

学了多年的算法,最短路问题相当之常见———— 好久没写过最短路的问题了,直到昨天闲的无聊来了一题——BZOJ3402(HansBug:额才发现我弱到只能刷水的地步了TT) 一看这不是明显的单源最短路么呵呵...于是直接上来来了个dijkstra,而且用的是邻接表存储图—— Submit之后,结果却是—— 我立刻被雷到了QAQ...于是立刻改写spfa,结果—— 4000ms+(估计还不止)和192ms究竟是怎样的差距啊QAQ,本人虽然早都听说过spfa的强大性,但是未曾想过差距会如此可怕,于是H