最短路算法大杂烩

最短路算法主要有以下几个:

一 Dijkstra

二 Bellman-Ford

三 SPFA

四 ASP

五 Floyd-Warshall

首先约定一下图的表示:

struct Edge{
         int
from,to,wt;
     };
    
vector<int>G[N];
    
vector<Edge>G[N];

-------------Dijkstra算法

使用条件:无负权边

复杂度O:((V+E)*log(V))

下面是用优先队列实现的Dijkstra算法


//Dijkstra 优先队列版
#include<iostream>
#include<iomanip>
#include<cstring>
#include<stdio.h>
#include<map>
#include<cmath>
#include<algorithm>
#include<vector>
#include<stack>
#include<fstream>
#include<queue>
#define rep(i,n) for(int i=0;i<n;i++)
#define fab(i,a,b) for(int i=(a);i<=(b);i++)
#define fba(i,b,a) for(int i=(b);i>=(a);i--)
#define MP make_pair
#define PB push_back
#define cls(x) memset(x,0,sizeof(x))
const int INF=0x7ffffff;
using namespace std;
const int N=1005;
struct Edge{
int from,to,w;
}edges[N];
vector<Edge>G[N];
typedef pair<int,int>PII;

int d[N];
void Dijkstra(int s){
priority_queue<PII,vector<PII>,greater<PII> >Q;
fill(d,d+N,INF);
d[s]=0;
Q.push(MP(d[s],s));
while(!Q.empty()){
PII cur=Q.top();Q.pop();
int u=cur.second;
if(cur.first!=u)continue;
rep(i,G[u].size()){
int to=G[u][i].to;
int w=G[u][i].w;
if(d[to]>d[u]+w){
d[to]=d[u]+w;
Q.push(MP(d[to],to));
}
}
}
}

-------Bellman-Ford 算法


//Bellman-Ford 可判断负权环
//复杂度O(VE)
int n;// number of node
int m;// number of edge
bool Bellman_Ford(int s){
fill(d,d+N,INF);
d[s]=0;
rep(i,n){
bool update=0;
rep(j,m){
Edge &e=edges[j];
if(d[e.to]>d[e.from]+e.w){
d[e.to]=d[e.from]+e.w;
update=1;
}
}
if(!update)return true;
if(i==n-1&&update)return false;
}
}

------SPFA算法

spfa是对bellman算法的改进,改进了bellman盲目更新的顺序,用类似于dijkstra的队列来更新节点。

基本流程:开始节点s队列,对s的每一个邻接点v更新,如果v不在队列则进队,直到队列为空。如何判断负环呢?因为最短路最多包含V-1条边,因此每一个节点(包括源点s)最多入队V次,所以如果有节点入队V+1次,说明存在负环。


//SPFA  复杂度...据说是O(KE)   k<<V
bool inqueue[N];
int cnt[N]={0};
bool SPFA(int s){
queue<int>Q;
cls(inqueue);
cls(cnt);
fill(d,d+N,INF);
d[s]=0;
Q.push(s);
inqueue[s]=1;
while(!Q.empty()){
int u=Q.front();Q.pop();
inqueue[u]=0;
rep(i,G[u].size()){
int to=G[u][i].to;
int w=G[u][i].w;
if(d[to]>d[u]+w){
d[to]=d[u]+w;
if(!inqueue[to]){
Q.push(to);
inqueue[to]=1;
if(++cnt[to]>n)return false;
}
}
}
}
return true;
}

------ASP算法

asp算法适用范围小,只能用于有向无环图,思想是dp,按拓扑序列更新节点复杂度O(N)


//asp复杂度O(N) 无环
int ind[N];
void ASP(int s){
cls(ind);
fill(d,d+N,INF);
queue<int>Q;
Q.push(s);
rep(i,m)++ind[edges[i].to];
rep(i,n)if(ind[i]==0)Q.push(i);
d[s]=0;
while(!Q.empty()){
int u=Q.front();Q.pop();
rep(i,G[u].size()){
int to=G[u][i].to;
int w=G[u][i].w;
if(d[to]>d[u]+w){
d[to]+d[u]+w;
}
if(--ind[to]==0)Q.push(to);
}
}
}

-----Floyd-Wallshall 多源最短路


//多源最短路径 Floyd-Warshall O(N^3)
int d[N][N];
void Floyd_Wallshall(){
rep(k,n){
rep(i,n){
rep(j,n){
if(d[i][j]>d[i][k]+d[k][j]){
d[i][j]=d[i][k]+d[k][j];
}
}
}
}
}

最短路算法大杂烩,布布扣,bubuko.com

时间: 2024-10-11 18:13:26

最短路算法大杂烩的相关文章

【啊哈!算法】算法7:Dijkstra最短路算法

上周我们介绍了神奇的只有五行的Floyd最短路算法,它可以方便的求得任意两点的最短路径,这称为“多源最短路”.本周来来介绍指定一个点(源点)到其余各个顶点的最短路径,也叫做“单源最短路径”.例如求下图中的1号顶点到2.3.4.5.6号顶点的最短路径. <ignore_js_op> 与Floyd-Warshall算法一样这里仍然使用二维数组e来存储顶点之间边的关系,初始值如下. <ignore_js_op> 我们还需要用一个一维数组dis来存储1号顶点到其余各个顶点的初始路程,如下.

最短路算法汇总

校赛完了,这次校赛,做的很差,一个算法题没有,2个水题,1个贪心,概率DP,DP,数论题.DP还没开始研究,数论根本不会,数学太差了,省赛时卡数论,校赛依然卡数论,我擦,还是得继续学习啊! 一把锈迹斑斑的剑,只有不断的磨砺,才能展露锋芒! 以下为最短路总结: 最短路问题可分为: 一.单源最短路径算法,解决方案:Bellman-Ford算法,Dijkstra算法,SPFA 二.每对顶点间的最短路径算法:Floyd: (1).Dijkstra算法: (经典的算法,可以说是最短路问题的首选事例算法,但

最短路算法及其延伸

个人算法训练题集:http://acm.hust.edu.cn/vjudge/contest/toListContest.action#contestType=0&contestRunningStatus=0&contestOpenness=0&title=风斩冰华&manager= 密码xwd,欢迎大家一起来学习. 首先复习一下最短路问题,即求某两点之间边权最小的一条路径.这样就延伸出了两个子问题: 求任意两点的距离,还是求图上固定一个起点到某点的距离? 验题:http:

【啊哈!算法】算法6:只有五行的Floyd最短路算法

暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计划旅程,小哼希望在出发之前知道任意两个城市之前的最短路程. 上图中有4个城市8条公路,公路上的数字表示这条公路的长短.请注意这些公路是单向的.我们现在需要求任意两个城市之间的最短路程,也就是求任意两个点之间的最短路径.这个问题这也被称为“多源最短路径”问题. 现在需要一个数据结构来存储图的信息,我们仍然可以用一个4*4的矩阵(二维数组e)来存储.比如1号城市到2号城市的路程为2,则设e[1][2]

近十年one-to-one最短路算法研究整理【转】

前言:针对单源最短路算法,目前最经典的思路即标号算法,以Dijkstra算法和Bellman-Ford算法为根本演进了各种优化技术和算法.针对复杂网络,传统的优化思路是在数据结构和双向搜索上做文章,或者针对不必要的循环进行排除.近年来,最短路算法大量应用于需要高及时性的领域,比如GIS领域,也大量应用于网络规模巨大的社会网络分析领域,这使得传统思路并不能很好地解决,于是把最短路算法思路本身抽象成两阶段算法,第一阶段为数据预处理,第二阶段为实时地搜索.这二者是互相矛盾的,如何找到平衡是各种算法技术

dijkstra(迪杰斯特拉)最短路算法的堆优化

dijkstra(迪杰斯特拉)最短路算法是一种时间复杂度经过严格证明的最短路算法. 优化在于每次取最小值的时候采用堆优化,但是在最短路松弛过程中,dist是不断修改的,所以,为了能使复杂度降到O(nlogn),dist修改的同时,在堆中也要修改. 注意dijkstra(迪杰斯特拉)最短路算法只能用于正权边. 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algo

Book 最短路算法

用HDU2544整理一下最近学的最短路算法 1.Dijkstra算法 原理:集合S表示已经找到最短路径的点,d[]表示当前各点到源点的距离 初始时,集合里面只有源点,当每个点u进入集合S时,用d[u]+w[u][v]更新距离 再重复这个步骤,选取S外所有点中d[]最小的进入集合 直到所有的点都进入S集合 局限性:图的边权必须为正 复杂度:O(V*V),堆优化((E+V)logV) (1)用邻接矩阵实现 1 #include<iostream> 2 #include<cstdio>

hdu 4568 spfa 最短路算法+旅行商问题

http://acm.hdu.edu.cn/showproblem.php?pid=4568 Problem Description One day, a hunter named James went to a mysterious area to find the treasures. James wanted to research the area and brought all treasures that he could. The area can be represented a

最短路算法 :Bellman-ford算法 &amp; Dijkstra算法 &amp; floyd算法 &amp; SPFA算法 详解

 本人QQ :2319411771   邮箱 : [email protected] 若您发现本文有什么错误,请联系我,我会及时改正的,谢谢您的合作! 本文为原创文章,转载请注明出处 本文链接   :http://www.cnblogs.com/Yan-C/p/3916281.html . 很早就想写一下最短路的总结了,但是一直懒,就没有写,这几天又在看最短路,岁没什么长进,但还是加深了点理解. 于是就想写一个大点的总结,要写一个全的. 在本文中因为邻接表在比赛中不如前向星好写,而且前向星效率并