图论$\cdot$最短路问题

  • Dijkstra单源最短路径算法

Dijkstra可以计算出发点到每个点的最短路,及单源最短路径(SSSP)。这一特点使得Dijkstra常常用来进行其他算法的预处理。用Dijkstra算法计算最短路的代码如下:

注:代码注释参见《算法竞赛入门经典——训练指南》(刘汝佳)

 1 struct Dijkstra{
 2     int n, m;
 3     vector<E> e;
 4     vector<int> G[maxn];
 5     bool done[maxn];
 6     int d[maxn];
 7     int p[maxn];
 8     void init(int n){
 9         this->n = n;
10         FOR(i, 0, n - 1) G[i].clear();
11         e.clear();
12     }
13     void addE(int from, int to, int dist){
14         e.pb(E(from, to, dist));
15         m = e.size();
16         G[from].pb(m - 1);
17     }
18     void dijkstra(int s){
19         priority_queue<HeapNode> Q;
20         FOR(i, 0, n - 1) d[i] = int_inf;
21         d[s] = 0;
22         clr(done, 0);
23         Q.push(HeapNode(0, s));
24         while(!Q.empty()){
25             HeapNode x = Q.top(); Q.pop();
26             int u = x.u;
27             if(done[u]) continue;
28             done[u] = 1;
29             int sz = G[u].size();
30             FOR(i, 0, sz - 1){
31                 E &y = e[G[u][i]];
32                 if(d[y.to] > d[u] + y.dist){
33                     d[y.to] = d[u] + y.dist;
34                     p[y.to] = G[u][i];
35                     Q.push(HeapNode(d[y.to], y.to));
36                 }
37             }
38         }
39     }
40 };
  • Bellman-Ford算法

Bellman-Ford算法的一个重要应用是判负圈。在迭代$n-1$次后如果还可以进行松弛(relax)操作,说明一定存在负圈。如果采用队列实现,那么当某个结点入队了$n$次时可以判断出存在负圈,代码如下:

 1 struct Bellman_Ford{
 2     int n, m;
 3     vector<E> e;
 4     vector<int> G[maxn];
 5     bool inq[maxn];
 6     int d[maxn];
 7     int p[maxn];
 8     int cnt[maxn];
 9     void init(int n){
10         this->n = n;
11         FOR(i, 0, n - 1) G[i].clear();
12         e.clear();
13     }
14     void addE(int from, int to, int dist){
15         e.pb(E(from, to, dist));
16         m = e.size();
17         G[from].pb(m - 1);
18     }
19     bool negCyc(){
20         queue<int> Q;
21         clr(inq, 0), clr(cnt, 0);
22         FOR(i, 0, n - 1) d[i] = 0, inq[i] = 1, Q.push(i);
23         while(!Q.empty()){
24             int u = Q.front(); Q.pop();
25             inq[u] = 0;
26             int sz = G[u].size();
27             FOR(i, 0, sz - 1){
28                 E &y = e[G[u][i]];
29                 if(d[y.to] > d[u] + y.dist){
30                     d[y].to = d[u] + y.dist;
31                     p[e.to] = G[u][i];
32                     if(!inq[y.to]){
33                         Q.push(y.to);
34                         inq[y.to] = 1;
35                         if(++cnt[y.to] > n) return 1;
36                     }
37                 }
38             }
39         }
40         return 0;
41     }
42 };
时间: 2025-01-04 00:05:36

图论$\cdot$最短路问题的相关文章

一周图论

图论周结束了.时间过得真是快啊!一周一周地,就溜走了. 下面写一下这周的收获吧. 最短路问题: (1)dijkstra算法 用vector开邻接表形式存储,利用优先队列优化: #include<queue> #include<vector> #include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> using namespace std; c

最短路问题(Bellman/Dijkstra/Floyd)

最短路问题(Bellman/Dijkstra/Floyd) 寒假了,继续学习停滞了许久的算法.接着从图论开始看起,之前觉得超级难的最短路问题,经过两天的苦读,终于算是有所收获.把自己的理解记录下来,可以加深印象,并且以后再忘了的时候可以再看.最短路问题在程序竞赛中是经常出现的内容,解决单源最短路经问题的有bellman-ford和dijkstra两种算法,其中,dijikstra算法是对bellman的改进.解决任意两点间的最短路有Floyd-warshall算法. 单源最短路1(bellman

P103 Dijkstra算法 单源最短路问题优化算法

///标准的dijkstra算法 void dijkstra() { while(true) { int vert=-1; dis[-1]=INF; for(int i=0;i<num_v;i++) { if( (!used[i]) && ( vert==-1||dis[i]<dis[vert] ) ) {vert=i;} } if(vert==-1) break;///这里要提前break;好像是这样... used[vert]=1; for(int i=0;i<num

最短路问题

一 Dijkstra算法 /*HDU2544 Input 每组数据第一行是两个整数N.M(N<=100,M<=10000)N表示成都的大街上有几个路口, 标号为1的路口是商店所在地,标号为N的路口是赛场所在地,M则表示在成都有几条路. N=M=0表示输入结束.接下来M行,每行包括3个整数A,B,C(1<=A,B<=N,1<=C<=1000), 表示在路口A与路口B之间有一条路,我们的工作人员需要C分钟的时间走过这条路. Output 对于每组输入,输出一行,表示工作人员

P100 单源最短路问题 Bellman-Ford 算法

///单源最短路问题 ///DAG:单向不循环图 ///问题的特殊性:要对变进行遍历,而不是顶点 const int MAX_V=; const int MAX_E=; const int INF=; int num_v; int num_e; int start; int aim; struct edge { int from; int to; int cost; }; edge G[MAX_E]; int dis[MAX_V]; void min_path(int start) { for(

UVA 10986 Sending email 最短路问题

基本的最短路问题 就是数据需要稍微处理一下.(N比较大)dijkstra也要优化.不优化应该会T: #include <map> #include <set> #include <list> #include <cmath> #include <ctime> #include <deque> #include <stack> #include <queue> #include <cctype> #i

编程算法 - 单源最短路问题 Bellman-Ford 代码(C)

单源最短路问题 Bellman-Ford 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 单源最短路: 固定一个起点, 求它到其他所有点的最短路的问题. Bellman-Ford: 设当前到顶点i的最短路长度为d[i], 并设初值d[s]=0, d[i]=INF, 再不断使用递推关系式d[e.to] = d[e.from] + e.cost更新d的值. 时间复杂度: O(V*E) 代码: /* * CppPrimer.cpp * * Created

最短路问题专题

///注意:最短路问题均没有使用递归函数. /* Dijkstra 单源最短路问题 用了一个队列 Bellman_Ford 单源最短路 暴搜 Floyd_warshanll 多元最短路问题 dp 直接更新 Dijkstra算法的路径还原*/ Dijkstra算法 Bellman_Floyd算法 Floyd_warshall算法 单源最短路问题 对所有的边进行遍历,更新d的数字 Bellman——floyd 暴力破解 === const int MAX_E; const int MAX_V; co

寒假集训日志(一)——图,最短路问题

今天主要学习了图的有关内容,以及DFS,BFS,最短路问题的大致讲解,做了4道习题,完成了今日任务. 最短路的三种算法: 1.Dijkstra算法(使用连接矩阵,打起来简单,但是复杂度高) 2.Bellman Ford算法(松弛操作, 使用较少) 3.SFPA算法(第一种算法的优化,使用最多) 另外,求两个点之间的最短路:Floyd算法 今天做的4道题: A - 最短路 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:

[NOIP 2014复习]第五章:图论

一.最短路问题 1.图的存储方式 2.Floyd算法求多源最短路 3.Dijsktra算法求单源最短路 4.Bellman-Ford算法求单源最短路 5.SPFA求单源最短路 (1)Wikioi 1173 最优贸易 题目描述 Description [问题描述] C 国有n 个大城市和m 条道路,每条道路连接这n 个城市中的某两个城市.任意两个 城市之间最多只有一条道路直接相连.这m 条道路中有一部分为单向通行的道路,一部分 为双向通行的道路,双向通行的道路在统计条数时也计为1 条. C 国幅员