首先两个算法都是常用于 求单源最短路径

关键部分就在于松弛操作 实际上就是dp的感觉

if (dist[e.to] > dist[v] + e.cost)

{

  dist[e.to] = dist[v] + e.cost;  

  ...

}

bellman_ford O(E*V) 但是配合队列可以 有spfa 可以达到O(kE)

http://www.360doc.com/content/13/1208/22/14357424_335569176.shtml

并且bellman_ford还适用于负边 并且可以利用最多循环V-1次的性质 判断是否存在负圈(如果循环超过V-1次 说明有负圈 因为没重复走着负圈一次 都伴随着更新)

并且因为松弛操作是针对于每条边的遍历也可以用向前星存

 #include <iostream>
#include <stdio.h>
#include <fstream>
#include <string.h>
#define MAXV 10007
#define MAXE 1007
#define INF 0x3f3f3f3f
using namespace std; int V, E; struct Edge
{
int from, to, cost;
}edge[MAXE]; int bellman_ford(int s, int d)//求单源最短路径
{
int dist[MAXV];
fill (dist, dist+V+, INF);
dist[s] = ;
while (true)//直至update不在更新
{
bool update = false;
for (int i = ; i < E; i++)
{
if (dist[edge[i].from] != INF && dist[edge[i].to] > dist[edge[i].from] + edge[i].cost)
{
dist[edge[i].to] = dist[edge[i].from] + edge[i].cost;
update = true;
}
}
if (!update) break;
}
return dist[d];
}
//while(true) 循环中最多循环V-1次 复杂度是O(V*E)
//如果存在 从s可达的负圈 那么在第V次循环时也会更新 可以用这个性质来检查负圈
//如果一开始把dist都初始化为0 那么可以检查出所有的负圈
//检查负边 是负边 返回true
//P.S 圈表示基本回路
bool isNegtive()
{
int dist[MAXV];
memset(dist, , sizeof(dist));//单纯查负圈
for (int i = ; i < V; i++)
{
for (int i = ; i < E; i++)
{
Edge e = edge[i];
if (dist[e.to] < dist[e.from] + e.cost )
{
dist[e.to] = dist[e.from] + e.cost;
if (i == V-)//如果第V次还更新 那么就有负圈
return true;
}
}
}
return false;
}
int main()
{
ifstream cin ("in.txt");
cin >> V >> E;
for (int i = ; i < E; i++)
{
cin >> edge[i].from >> edge[i].to >> edge[i].cost;
}
cout << bellman_ford(, ) << endl;
}

dijkstra 普通写法O(V^2)

但是 dijkstra的特点 --->>是针对每一个点 通过它所对应的边更新 e.to的节点

每次取出的是离原点sorce 最近的点 所以就可以使用优先队列 那么就变成O(V*logV)

并且因为“是针对每一个点 通过它所对应的边更新 e.to的节点 ” 那么也很好试用向前星

 #include <iostream>
#include <string.h>
#include <fstream>
#include <stdio.h>
#include <queue>
#define MAXV 10007
#define MAXE 1007
#define INF 0x3f3f3f3f
using namespace std; int V, E;
//迪杰特斯拉好像不是很好用向前星
//这个算法是针对每一个点更新 而向前星存储的是边的信息 要查找点就比较复杂 //用邻接矩阵存储 O(V^2)的算法 int cost[MAXV][MAXV];
int dijkstra(int s, int d)
{
int dist[MAXV];
bool use[MAXV];
fill(dist, dist+MAXV, INF);
memset(use, false, sizeof(use));
dist[s] = ;
while (true)
{
int v = -;
for (int i = ; i <= V; i++)//找一个最近的 未使用过的点
{
if (!use[i] && (v == - || dist[i] < dist[v])) v = i;
}
if (v == -) break;
use[v] = true;
for (int i = ; i <= V; i++)
{
dist[i] = min(dist[i], dist[v] + cost[v][i]);
}
}
return dist[d];
} //使用优先队列(也就是heap优化)O(E*logV)
//针对边来dp 这里可以用向前星存储了
struct Edge
{
int to, n, next;
}edge[MAXE];
int num = ;
int head[MAXV];
void Add(int from, int to, int c)
{
edge[num].n = c;
edge[num].to = to;
edge[num].next = head[from];//从头插入
head[from] = num++;
}
void init()//初始化
{
ifstream cin("in.txt");
memset(edge, -, sizeof(edge));
memset(head, -, sizeof(head));
cin >> V >> E;
for (int j = ; j < E; j++)
{
int from , to , c;
cin >> from >> to >> c;
Add(from, to, c);
}
} typedef pair<int, int> P;//first 表示与s的距离, second表示点的编号
int pre[MAXV];//记录前驱节点 在每次dist[j] = dist[k] + cost[k][j]更新时记录在到j的最短路径上的前驱节点就是k
int fast_dijkstra(int s, int d)
{
int dist[MAXV];
priority_queue<P, vector<P>, greater<P> > que;//用优先队列存储点的信息 每次弹出距离最短的点O(logV)
fill(dist, dist+MAXV, INF);
dist[s] = ;
que.push(P(, s));
while (!que.empty())
{
P p = que.top();
que.pop();
if (dist[p.second] < p.first) continue;
int t = head[p.second];
while (t != -)
{
Edge e = edge[t];
if (dist[e.to] > dist[p.second] + e.n)
{
dist[e.to] = dist[p.second] + e.n;
pre[e.to] = p.second;
que.push( P(dist[e.to], e.to) );
}
t = e.next;
}
}
return dist[d];
} int main()
{
/*
ifstream cin("in.txt");
cin >> V >> E;
for (int i = 1; i <= V; i++)
for (int j = 1; j <= V; j++)
cost[i][j] = INF;//不存在时 cost为INF
for (int j = 0; j < E; j++)
{
int from , to , c;
cin >> from >> to >> c;
cost[from][to] = c;
}
int ans = dijkstra(1, 7);
*/
init();
int ans = fast_dijkstra(,);
cout << ans << endl;
//这样路径即还原了
int t = pre[];
cout << << " ";
while(t != )
{
cout << t << " ";
t = pre[t];
}
cout << <<endl;
}

单源最短路径 Bellman_ford 和 dijkstra的更多相关文章

  1. 单源最短路径问题2 (Dijkstra算法)

    用邻接矩阵 /* 单源最短路径问题2 (Dijkstra算法) 样例: 5 7 0 1 3 0 3 7 1 2 4 1 3 2 2 3 5 2 4 6 3 4 4 输出: [0, 3, 7, 5, 9 ...

  2. 图论(四)------非负权有向图的单源最短路径问题,Dijkstra算法

    Dijkstra算法解决了有向图G=(V,E)上带权的单源最短路径问题,但要求所有边的权值非负. Dijkstra算法是贪婪算法的一个很好的例子.设置一顶点集合S,从源点s到集合中的顶点的最终最短路径 ...

  3. 单源最短路径问题之dijkstra算法

    欢迎探讨,如有错误敬请指正 如需转载,请注明出处 http://www.cnblogs.com/nullzx/ 1. 算法的原理 以源点开始,以源点相连的顶点作为向外延伸的顶点,在所有这些向外延伸的顶 ...

  4. 非负权值有向图上的单源最短路径算法之Dijkstra算法

    问题的提法是:给定一个没有负权值的有向图和其中一个点src作为源点(source),求从点src到其余个点的最短路径及路径长度.求解该问题的算法一般为Dijkstra算法. 假设图顶点个数为n,则针对 ...

  5. 单源最短路径—Bellman-Ford和Dijkstra算法

    Bellman-Ford算法:通过对边进行松弛操作来渐近地降低从源结点s到每个结点v的最短路径的估计值v.d,直到该估计值与实际的最短路径权重相同时为止.该算法主要是基于下面的定理: 设G=(V,E) ...

  6. 洛谷 P3371 【模板】单源最短路径(堆优化dijkstra)

    题目描述 如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度. 输入输出格式 输入格式: 第一行包含三个整数N.M.S,分别表示点的个数.有向边的个数.出发点的编号. 接下来M行每行包含三 ...

  7. 【算法】Dijkstra算法(单源最短路径问题)(路径还原) 邻接矩阵和邻接表实现

    Dijkstra算法可使用的前提:不存在负圈. 负圈:负圈又称负环,就是说一个全部由负权的边组成的环,这样的话不存在最短路,因为每在环中转一圈路径总长就会边小. 算法描述: 1.找到最短距离已确定的顶 ...

  8. Bellman-Ford算法 - 有向图单源最短路径

    2017-07-27  08:58:08 writer:pprp 参考书目:张新华的<算法竞赛宝典> Bellman-Ford算法是求有向图单源最短路径的,dijkstra算法的条件是图中 ...

  9. Dijkstra 单源最短路径算法

    Dijkstra 算法是一种用于计算带权有向图中单源最短路径(SSSP:Single-Source Shortest Path)的算法,由计算机科学家 Edsger Dijkstra 于 1956 年 ...

随机推荐

  1. Mysql多表联合更新、删除

    UPDATE snyts_user u INNER JOIN snyts_order o ON u.user_id = o.user_id INNER JOIN snyts_refund_order ...

  2. 【数据分析 R语言实战】学习笔记 第七章 假设检验及R实现

    假设检验及R实现 7.1假设检验概述 对总体参数的具体数值所作的陈述,称为假设;再利用样本信息判断假设足否成立,这整个过程称为假设检验. 7.1.1理论依据 假设检验之所以可行,其理沦背景是小概率理论 ...

  3. JavaScript 的垃圾回收与内存泄露

    JavaScript采用垃圾自动回收机制,运行时环境会自动清理不再使用的内存,因此javascript无需像C++等语言一样手动释放无用内存. 在这之前先说一下垃圾回收的两种方式:引用计数与标记清除. ...

  4. Javascript异步编程的常用方法

    Javascript语言的执行环境是"单线程"(single thread).所谓"单线程",就是指一次只能完成一件任务.如果有多个任务,就必须排队,前面一个任 ...

  5. zipkin 服务追踪

    服务追踪,就是对请求接口的追踪并保存. 在测试的过程中我们会发现,有时候,程序刚刚启动后,刷新几次,并不能看到任何数据,原因就是我们的spring-cloud-sleuth收集信息是有一定的比率的,默 ...

  6. iview 的 Carousel 走马灯 焦点图 不能用 建议换/vue-awesome-swiper

    https://www.npmjs.com/package/vue-awesome-swiper

  7. G7或变G6+1?特朗普七国峰会箱友军开炮

    今日导读 G7 峰会刚召开完毕,德国总理默克尔发的一张照片就迅速火遍全球.照片中她身体前倾,像是在质问特朗普,而后者则双手交叉胸前,我自岿然不动,这张火药味十足的照片不禁让人脑补当时剑拔弩张的气氛.到 ...

  8. ORA-03113: end-of-file on & ORA-07445

    --------------ORA-03113: end-of-file on-------------- SQL> show parameter background_dump; NAME T ...

  9. SQL Server 2008 空间数据存储摘抄(SRID 点 MultiPoint LineString MultiLineString 多边形 MultiPolygon GeometryCollection)

    有两种类型的空间数据.geometry 数据类型支持平面或欧几里得(平面球)数据.geometry 数据类型符合适用于 SQL 规范的开放地理空间联盟 (OGC) 简单特征 1.1.0 版. 另外,S ...

  10. check.pl

    比对两个文件并纠错 #!/usr/bin/perl use strict; use warnings; ###############################################m ...