`
阿尔萨斯
  • 浏览: 4146211 次
社区版块
存档分类
最新评论

Bellman_Ford算法->SPFA算法

 
阅读更多

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

    图论- 最短路- Bellman-Ford 算法与 SPFA.rar

    图论,ACM SPFA 和Bellman_ford.ppt 最短路算法

    这里面的内容是个PPT,介绍的很好,如果你想更加的清楚 SPFA 和Bellman_ford.ppt 最短路算法的原理,这是个不错的选择

    蓝桥杯CJ2-11-图论最短路径问题 Bellman-Ford算法+SPFA.pdf

    蓝桥杯CJ2-11-图论最短路径问题 Bellman-Ford算法+SPFA.pdf

    队列优化的Bellmanford最短路算法(SPFA)C++实现

    使用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算法

    SPFA算法.zip

    在之前的Bellman-Ford算法中存在一个重复更新的问题,即每个枢纽点都要对全部顶点更新计算 SPFA算法就解决了重复计算的问题,在大数据面前大大减少运行时间 该算法改善的思想是避免顶点进行无效的重复更新,对有待...

    SPFA带负权的最短路径算法

    SPFA 算法是 Bellman-Ford算法 的队列优化算法的别称,通常用于求含负权边的单源最短路径,以及判负权环。SPFA 最坏情况下复杂度和朴素 Bellman-Ford 相同,为 O(VE)。

    Bellman Ford

    Bellman Ford SPFA 算法的相关资料~~~~

    SPFA算法模板

    求单源最短路的SPFA算法的全称是:Shortest Path Faster Algorithm。...很多时候,给定的图存在负权边,这时类似Dijkstra等算法便没有了用武之地,而Bellman-Ford算法的复杂度又过高,SPFA算法便派上用场了。

    SPFA.cpp SPFA算法

    最短路SPFA算法。SPFA(Shortest Path Faster Algorithm)算法是求单源最短路径的一种算法,它是Bellman-ford的队列优化,它是一种十分高效的最短路算法。存在负权边时使用。

    ACM算法模板和pku代码

    最大流:Ford&Fulkerson算法 最大流:Dinic算法 最大流:ek算法 最大流:dsp算法 最大流:hlpp算法 最小费用最大流:bellman_ford找增广路 最小费用最大流:ssp算法 字符串 KMP 通配符匹配 最小表示法 ...

    寻路测试2源代码

    实现算法:DFS,BFS,双向BFS,一个自己的启发式,Bellman-Ford,Dijkstrra,SPFA,A*

    idsc_shapematching:林海滨的形状匹配算法

    idsc_shapematching 林海滨的形状匹配算法我在此算法中解决了两个问题。 第一个是他的角度矩阵,该角度矩阵是... 我使用spfa优化bellman_ford。 其次,我解决了对称性问题。 它在Elephant.bmp和Elephant34.bmp中显示。

    最短路径问题

    详细描述了解决最短路径问题的方法,包括:Dijkstra算法,Bellman-Ford算法 SPFA算法,以及一些习题。

    寻路测试2可执行

    实现算法: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 广度...

    suanfa.rar_SPFA

    C++队列优化的Bellmanford最短路算法(SPFA),使用C++实现的Queue improved Bellman-Ford单源最短路算法,在国内还被叫做SPFA。这个程序输入一个图,找到图中的一个点,这个点到最远点的长度最短。图使用邻接表保存...

    职业:经典算法集

    Bellman–Ford算法LC743 Dijkstar的算法无法处理负权重边缘,但Bellman-Ford可以。 Floyd–Warshall算法LC1462 最短路径更快算法(SPFA) LC743 在Bellman-Ford之上的改进 约翰逊算法 基数排序 联合发现LC

Global site tag (gtag.js) - Google Analytics