最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++圖論之Bellman-Ford算法和SPFA算法的實(shí)現(xiàn)

 更新時(shí)間:2022年06月14日 15:55:15   作者:玄澈_  
貝爾曼-福特算法(Bellman-Ford)是由理查德·貝爾曼和萊斯特·福特創(chuàng)立的,求解單源最短路徑問題的一種算法。SPFA 算法是 Bellman-Ford算法 的隊(duì)列優(yōu)化算法的別稱,通常用于求含負(fù)權(quán)邊的單源最短路徑。本文將詳解兩個(gè)算法的實(shí)現(xiàn),需要的可以參考一下

給定一張有向圖,若對(duì)于圖中的某一條邊(x,y,z),有dist[y]≤dist[x]+z成立,則稱該邊滿足三角形不等式。如果所有邊都滿足三角形不等式,則dist數(shù)組就是所求的最短路。

Bellman-Ford算法

(x,y,z)表示的是一條從 x 出發(fā), 到達(dá) y ,長度為 z 的有向邊。

首先介紹基于迭代的Bellman-Ford算法,它的流程如下:

1.掃描所有邊(x,y,z),若dist[y]>dist[x]+z, 則用dist[x]+z更新dist[y]

2.重復(fù)上述操作,直到?jīng)]有更新操作發(fā)生。

Bellman-Ford算法的時(shí)間復(fù)雜度是O(nm)

通過Bellman-Ford算法我們可以求解有邊數(shù)限制的最短路問題。

例題:AcWing 853. 有邊數(shù)限制的最短路

算法步驟

初始化 dist 數(shù)組為正無窮, dist[1] = 0

(外重循環(huán))循環(huán) i 從 1 到 n ,遍歷 n 次表示:是不經(jīng)過超過 i 條邊到達(dá)終點(diǎn)的最短距離

(內(nèi)重循環(huán))循環(huán) i 從 1 到 m, 遍歷 m 條邊,把所有的邊都進(jìn)行松弛操作:

每次取出兩點(diǎn)以及以及連接他們的權(quán)重 (a,b,w)

用以下公式更新最短距離: dist[b]=min(dist[b],dist[a]+w)

注意點(diǎn):

需要把dist數(shù)組進(jìn)行一個(gè)備份,這樣防止每次更新的時(shí)候出現(xiàn)串聯(lián)

由于存在負(fù)權(quán)邊,所以 return -1 的條件是dist[n]>0x3f3f3f/2

代碼實(shí)現(xiàn)

#include <iostream>
#include <cstring>
using namespace std;
 
const int N = 510, M = 10010;
 
struct Edge
{
    int a, b, w;
}e[M]; // 存下每一條即可
int dist[N];
int back[N]; // 備份數(shù)組放置串聯(lián)
int n, m, k;
 
void bellman_ford()
{
    memset(dist, 0x3f, sizeof dist);
    dist[1] = 0;
    
    for(int i = 0; i < k; i ++ ) // 不超過k條邊
    {
        memcpy(back, dist, sizeof back);
        for(int j = 0; j < m; j ++ ) // 遍歷所有邊
        {
            int a = e[j].a, b = e[j].b, w = e[j].w;
            dist[b] = min(dist[b], back[a] + w);
        }
    }
}
 
int main()
{
    cin >> n >> m >> k;
    for(int i = 0; i < m; i ++ )
    {
        int a, b, w;
        scanf("%d%d%d", &a, &b, &w);
        e[i] = {a, b, w};
    }
    
    bellman_ford();
    if(dist[n] > 0x3f3f3f3f / 2) puts("impossible");
    else cout << dist[n] << endl;
    
    return 0;
}

SPFA算法

SPFA算法在國際上通稱為“隊(duì)列優(yōu)化的“Bellman-Ford算法”。

SPFA算法的流程如下:

1.建立一個(gè)隊(duì)列,起初隊(duì)列中只含有起點(diǎn)1

2.取出頭結(jié)點(diǎn) x ,掃描它的所有出邊(x,y,z),若dist[y]>dist[x]+z,則使dist[y]用dist[x]+z來更新。同時(shí)若y不再隊(duì)列中,則將y入隊(duì)

在任意時(shí)刻,該算法的隊(duì)列都保持了該拓展的節(jié)點(diǎn)。每次入隊(duì)都相當(dāng)于完成了一次 dist 數(shù)組的更新操作,使其滿足三角不等式。一個(gè)節(jié)點(diǎn)可能會(huì)入隊(duì)、出隊(duì)多次。最終,圖中所有的結(jié)點(diǎn)全部收斂到全部滿足三角不等式的狀態(tài)。

這個(gè)隊(duì)列避免了對(duì)Bellman-Ford算法中不需要拓展的多余結(jié)點(diǎn)的冗余掃描,在隨機(jī)圖上的運(yùn)行效率O(km)級(jí)別,其中 k 是一個(gè)很小的常數(shù)。

代碼實(shí)現(xiàn)

SPFA求最短路

#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
 
using namespace std;
 
const int N = 1e6 + 10;
 
int n, m;
int h[N], e[N], w[N], ne[N], idx;
int dist[N];
bool st[N];
 
void add(int a, int b, int c)
{
    e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx ++ ;
}
 
void spfa()
{
    memset(dist, 0x3f, sizeof dist);
    queue<int> q;
    dist[1] = 0;
    st[1] = true;
    q.push(1);
    
    while(q.size())
    {
        int t = q.front();
        q.pop();
        
        st[t] = false;
        
        for(int i = h[t]; ~i; i = ne[i])
        {
            int j = e[i];
            if(dist[j] > dist[t] + w[i])
            {
                dist[j] = dist[t] + w[i];
                if(!st[j])
                {
                    q.push(j);
                    st[j] = true;
                }
            }
        }
    }
}
 
int main()
{
    scanf("%d%d", &n, &m);
 
    memset(h, -1, sizeof h);
    while (m -- )
    {
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c);
        add(a, b, c);
    }
 
    spfa();
    
    if(dist[n] == 0x3f3f3f3f) puts("impossible");
    else printf("%d",dist[n]);
 
    return 0;
}
 

以上就是C++圖論之Bellman-Ford算法和SPFA算法的實(shí)現(xiàn)的詳細(xì)內(nèi)容,更多關(guān)于C++ Bellman-Ford SPFA算法的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 基于curses庫實(shí)現(xiàn)彈球游戲

    基于curses庫實(shí)現(xiàn)彈球游戲

    這篇文章主要為大家詳細(xì)介紹了基于curses庫實(shí)現(xiàn)彈球游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • openCV中meanshift算法查找目標(biāo)的實(shí)現(xiàn)

    openCV中meanshift算法查找目標(biāo)的實(shí)現(xiàn)

    本文主要介紹了openCV中meanshift算法查找目標(biāo)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • OpenCV基于背景減除實(shí)現(xiàn)行人計(jì)數(shù)

    OpenCV基于背景減除實(shí)現(xiàn)行人計(jì)數(shù)

    本文主要介紹了如何使用OpenCV C++對(duì)視頻中的人流量進(jìn)行統(tǒng)計(jì)。文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)OpenCV有一定的幫助,需要的可以了解一下
    2022-01-01
  • C語言中#pragma?pack(1)的用法與注意點(diǎn)

    C語言中#pragma?pack(1)的用法與注意點(diǎn)

    #pragma用于指示編譯器完成一些特定的動(dòng)作,下面這篇文章主要給大家介紹了關(guān)于C語言中#pragma?pack(1)的用法與注意點(diǎn)的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-02-02
  • C++第三方日志庫Glog基本語法詳解

    C++第三方日志庫Glog基本語法詳解

    這篇文章主要介紹了C++第三方日志庫Glog基本語法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-02-02
  • C++實(shí)現(xiàn)LeetCode(97.交織相錯(cuò)的字符串)

    C++實(shí)現(xiàn)LeetCode(97.交織相錯(cuò)的字符串)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(97.交織相錯(cuò)的字符串),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C++之Qt5雙緩沖機(jī)制案例教程

    C++之Qt5雙緩沖機(jī)制案例教程

    這篇文章主要介紹了C++之Qt5雙緩沖機(jī)制案例教程,本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C++?stack用法總結(jié)(示例詳解)

    C++?stack用法總結(jié)(示例詳解)

    std::stack?是?C++?標(biāo)準(zhǔn)模板庫(STL)中的容器適配器,它提供了棧(stack)的功能,基于其他序列容器實(shí)現(xiàn),下面給大家介紹std::stack?的用法總結(jié),感興趣的朋友一起看看吧
    2024-01-01
  • wince程序防止創(chuàng)建多個(gè)實(shí)例實(shí)現(xiàn)互斥作用

    wince程序防止創(chuàng)建多個(gè)實(shí)例實(shí)現(xiàn)互斥作用

    什么時(shí)候用的互斥?當(dāng)你的程序只允許同時(shí)打開一個(gè)的時(shí)候,就可以通過互斥來實(shí)現(xiàn),下面說的互斥,主要是針對(duì)防止程序創(chuàng)建多個(gè)實(shí)例這種情況來實(shí)現(xiàn)的
    2014-02-02
  • OpenCV實(shí)現(xiàn)傾斜文字校正

    OpenCV實(shí)現(xiàn)傾斜文字校正

    這篇文章主要為大家詳細(xì)介紹了OpenCV實(shí)現(xiàn)傾斜文字校正,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08

最新評(píng)論

宁河县| 达州市| 张家川| 沙洋县| 石河子市| 唐河县| 龙陵县| 彰化县| 郑州市| 临邑县| 石屏县| 肃北| 河北省| 沁源县| 华安县| 福安市| 齐河县| 徐州市| 宝清县| 化隆| 定日县| 泰宁县| 新竹市| 嘉禾县| 桦南县| 阜康市| 桓台县| 北安市| 钦州市| 平陆县| 南宁市| 太湖县| 阿拉善右旗| 金寨县| 岚皋县| 阿尔山市| 筠连县| 沙河市| 通化市| 泰和县| 邻水|