Bellman_Ford算法->SPFA算法
刘汝佳算法入门经典P 205 与训练指南P 332 有关于Bellman_Ford算法的介绍和代码. 其实SPFA算法就是Bellman_Ford算法的(加上了判负圈的)队列实现版本.
下面给出3种Bellman_Ford算法的实现代码:
1.Bellman_Ford简单版
//Bellman_Ford算法简单形式
//求的是从0点到其他点的单源最短路径,复杂度O(n*m)
void Bellman_Ford()
{
for(int i=0;i<n;i++) d[i]=INF;
d[0]=0;
for(int k=0;k<n-1;k++) //迭代n-1次
for(int i=0;i<m;i++) //检查每条边
{
int x=u[i],y=v[i];
if(d[x]<INF) d[y] =min(d[y],d[x]+w[i]); //松弛
}
}
2.Bellman_Ford队列版
//Bellman_Ford算法队列实现
//求的是从0点到其他点的单源最短路径,复杂度O(n*m)
void Bellman_Ford()
{
queue<int> q;
bool inq[maxn];
for(int i=0;i<n;i++) d[i]= i==0?0:INF;
memset(inq,0,sizeof(inq));
q.push(0);
while(!q.empty())
{
int x=q.front(); q.pop();
inq[x]=false;
for(int e=first[x];e!=-1;e=next[e])
if(d[v[e]]> d[x]+w[e])
{
d[v[e]] = d[x]+w[e];
if(!inq[v[e]])
{
inq[v[e]]=true;
q.push(v[e]);
}
}
}
}
3.Bellman_Ford标准版_SPFA
//Bellman_Ford刘汝佳模板_SPFA(能判负圈)
//求的是从s点到其他点的单源最短路径,复杂度O(k*e)
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
#define INF 1e9
struct Edge
{
int from,to,dist;
Edge(int f,int t,int d):from(f),to(t),dist(d){}
};
struct BellmanFord
{
int n,m;
vector<Edge> edges;
vector<int> G[maxn];
bool inq[maxn]; //是否在队列中
int d[maxn]; //s到各个点的距离
int p[maxn]; //最短路中的上一条弧
int cnt[maxn]; //进队次数
void init(int n)
{
this->n=n;
for(int i=0;i<n;i++) G[i].clear();
edges.clear();
}
void AddEdge(int from,int to,int dist)
{
edges.push_back(Edge(from,to,dist));
m = edges.size();
G[from].push_back(m-1);
}
bool negativeCycle(int s)
{
queue<int> Q;
memset(inq,0,sizeof(inq));
memset(cnt,0,sizeof(cnt));
for(int i=0;i<n;i++) d[i]=INF;
inq[s]=true,d[s]=0,Q.push(s);
while(!Q.empty())
{
int u=Q.front(); Q.pop();
inq[u]=false;
for(int i=0;i<G[u].size();i++)
{
Edge &e=edges[G[u][i]];
if(d[e.to] > d[u]+e.dist)
{
d[e.to] = d[u]+e.dist;
p[e.to] = G[u][i];
if(!inq[e.to])
{
Q.push(e.to);
inq[e.to]=true;
if(++cnt[e.to]>n) return true;
}
}
}
}
return false;
}
}BF;
4.Bellman_Ford快速版_SPFA(内存消耗多)
//POJ1511题用到,用邻接表实现,避免了vector添加边信息的时间消耗
#include<algorithm>
#include<vector>
#include<queue>
#define INF 1e9
using namespace std;
const int maxn =1000000+10;
int n,m;
struct Edge
{
int from,to,dist;
Edge(){}
Edge(int f,int t,int d):from(f),to(t),dist(d){}
};
struct BellmanFord
{
int n,m;
int head[maxn]; //每个节点邻接表的头
int next[maxn];
Edge edges[maxn]; //所有的边信息
bool inq[maxn];
int d[maxn];
int p[maxn];
int cnt[maxn];
void init(int n)
{
this->n=n;
this->m=0;
memset(head,-1,sizeof(head));
}
void AddEdge(int from,int to,int dist)
{
edges[m]=Edge(from,to,dist);
next[m]=head[from];
head[from] = m++;
}
bool negativeCycle(int s)
{
queue<int> Q;
memset(inq,0,sizeof(inq));
memset(cnt,0,sizeof(cnt));
for(int i=0;i<n;i++) d[i]= i==s?0:INF;
Q.push(s);
while(!Q.empty())
{
int u=Q.front(); Q.pop();
inq[u]=false;
for(int i=head[u];i!=-1;i=next[i])
{
Edge &e=edges[i];
if(d[e.to] > d[u]+e.dist)
{
d[e.to] = d[u]+e.dist;
p[e.to] = i;
if(!inq[e.to])
{
inq[e.to]=true;
Q.push(e.to);
if(++cnt[e.to]>n) return true;
}
}
}
}
return false;
}
}BF1,BF2;
分享到:
相关推荐
图论- 最短路- Bellman-Ford 算法与 SPFA.rar
这里面的内容是个PPT,介绍的很好,如果你想更加的清楚 SPFA 和Bellman_ford.ppt 最短路算法的原理,这是个不错的选择
蓝桥杯CJ2-11-图论最短路径问题 Bellman-Ford算法+SPFA.pdf
使用C++实现的Queue improved Bellman-Ford单源最短路算法,在国内还被叫做SPFA。这个程序输入一个图,找到图中的一个点,这个点到最远点的长度最短。图使用邻接表保存。
单源最短路径(SPFA) Bellman-Ford(Queue-Optimised) 单源最短路径(Bellman-Ford) Bellman-Ford 双连通分量 Biconnected-Compotent 使用Edmonds-Karp进行二分图匹配 Bigrpah-Matching(Edmonds-Karp) 使用ISAP算法...
问题描述、算法结构、程序实现、结论 贪心算法原理、松弛技术、Bellman-Ford算法、SPFA算法
在之前的Bellman-Ford算法中存在一个重复更新的问题,即每个枢纽点都要对全部顶点更新计算 SPFA算法就解决了重复计算的问题,在大数据面前大大减少运行时间 该算法改善的思想是避免顶点进行无效的重复更新,对有待...
SPFA 算法是 Bellman-Ford算法 的队列优化算法的别称,通常用于求含负权边的单源最短路径,以及判负权环。SPFA 最坏情况下复杂度和朴素 Bellman-Ford 相同,为 O(VE)。
Bellman Ford SPFA 算法的相关资料~~~~
求单源最短路的SPFA算法的全称是:Shortest Path Faster Algorithm。...很多时候,给定的图存在负权边,这时类似Dijkstra等算法便没有了用武之地,而Bellman-Ford算法的复杂度又过高,SPFA算法便派上用场了。
最短路SPFA算法。SPFA(Shortest Path Faster Algorithm)算法是求单源最短路径的一种算法,它是Bellman-ford的队列优化,它是一种十分高效的最短路算法。存在负权边时使用。
最大流:Ford&Fulkerson算法 最大流:Dinic算法 最大流:ek算法 最大流:dsp算法 最大流:hlpp算法 最小费用最大流:bellman_ford找增广路 最小费用最大流:ssp算法 字符串 KMP 通配符匹配 最小表示法 ...
实现算法:DFS,BFS,双向BFS,一个自己的启发式,Bellman-Ford,Dijkstrra,SPFA,A*
idsc_shapematching 林海滨的形状匹配算法我在此算法中解决了两个问题。 第一个是他的角度矩阵,该角度矩阵是... 我使用spfa优化bellman_ford。 其次,我解决了对称性问题。 它在Elephant.bmp和Elephant34.bmp中显示。
详细描述了解决最短路径问题的方法,包括:Dijkstra算法,Bellman-Ford算法 SPFA算法,以及一些习题。
实现算法:DFS,BFS,双向BFS,一个自己的启发式,Bellman-Ford,Dijkstrra,SPFA,A*
单源最短路径(SPFA) Bellman-Ford(Queue-Optimised) 单源最短路径(Bellman-Ford) Bellman-Ford 使用Edmonds-Karp进行二分图匹配 Bigrpah-Matching(Edmonds-Karp) 普通的二叉搜索树 Binary-Search-Tree 广度...
C++队列优化的Bellmanford最短路算法(SPFA),使用C++实现的Queue improved Bellman-Ford单源最短路算法,在国内还被叫做SPFA。这个程序输入一个图,找到图中的一个点,这个点到最远点的长度最短。图使用邻接表保存...
Bellman–Ford算法LC743 Dijkstar的算法无法处理负权重边缘,但Bellman-Ford可以。 Floyd–Warshall算法LC1462 最短路径更快算法(SPFA) LC743 在Bellman-Ford之上的改进 约翰逊算法 基数排序 联合发现LC