国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

(迪杰斯特拉)Dijkstra算法及其優(yōu)化(C++)

這篇具有很好參考價值的文章主要介紹了(迪杰斯特拉)Dijkstra算法及其優(yōu)化(C++)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

題目原文

題目描述
給定一個 n n n 個點(diǎn) m m m 條邊的有向圖,圖中可能存在重邊和自環(huán),所有邊權(quán)均為非負(fù)值。
請你求出 1 1 1 號點(diǎn)到 n n n 號點(diǎn)的最短距離,如果無法從 1 1 1 號點(diǎn)走到 n n n 號點(diǎn),則輸出 ? 1 ?1 ?1。

輸入格式
第一行包含整數(shù) n n n m m m
接下來 m m m 行每行包含三個整數(shù) x , y , z , x,y,z, x,y,z, 表示存在一條從點(diǎn) x x x 到點(diǎn) y y y 的有向邊,邊長為 z z z。

輸出格式
輸出一個整數(shù),表示 1 1 1 號點(diǎn)到 n n n 號點(diǎn)的最短距離。
如果路徑不存在,則輸出 ? 1 ?1 ?1。

輸入樣例:

3 3
1 2 2
2 3 1
1 3 4

輸出樣例:

3

算法思想

算法背景:

迪杰斯特拉算法是由荷蘭計算機(jī)科學(xué)家在1956年發(fā)現(xiàn)的算法,是從一個頂點(diǎn)到其余各頂點(diǎn)的最短路徑算法,解決的是有權(quán)圖中最短路徑問題。迪杰斯特拉算法主要特點(diǎn)是從起始點(diǎn)開始,采用貪心算法的策略,每次遍歷到始點(diǎn)距離最近且未訪問過的頂點(diǎn)的鄰接節(jié)點(diǎn),直到擴(kuò)展到終點(diǎn)為止。

算法步驟如下:

  1. 初始化過程:初始時令 S = V 0 , T = V ? S = S={V_0},T=V-S= S=V0?,T=V?S= { 其余頂點(diǎn) },T中頂點(diǎn)對應(yīng)的距離值:
    若存在, d ( V 0 , V i ) d(V_0,V_i) d(V0?,Vi?) 為弧上的權(quán)值;
    若不存在, d ( V 0 , V i ) d(V0,Vi) d(V0,Vi) ∞ \infty
  2. 選取最短路徑過程:從 T T T 中選取一個與 S S S 中頂點(diǎn)有關(guān)聯(lián)邊且權(quán)值最小的頂點(diǎn) W W W ,加入到 S S S 中。
  3. 調(diào)整鄰接點(diǎn)距離過程:對其余 T T T 中頂點(diǎn)的距離值進(jìn)行修改:若加進(jìn) W W W 作中間頂點(diǎn),從 V 0 V_0 V0? V i V_i Vi? 的距離值縮短,則修改此距離值。
    重復(fù)上述步驟2、3,直到 S S S 中包含所有頂點(diǎn),即 W = V i W=V_i W=Vi?為止。

算法過程

題目原文 中輸入樣例為例(藍(lán)色代表 T T T,橙色代表 S S S):
開始時,1在 S S S 中,而2、3在 T T T 中,
(迪杰斯特拉)Dijkstra算法及其優(yōu)化(C++)

節(jié)點(diǎn) 距離
1 0
2 2
3 4

然后將距離為2的邊所對應(yīng)的節(jié)點(diǎn)2加入 S S S 中:
(迪杰斯特拉)Dijkstra算法及其優(yōu)化(C++)

節(jié)點(diǎn) 距離
1 0
2 2
3 3

最后將節(jié)點(diǎn)3加入 S S S 中:
(迪杰斯特拉)Dijkstra算法及其優(yōu)化(C++)

節(jié)點(diǎn) 距離
1 0
2 2
3 3

算法結(jié)束,題目所求節(jié)點(diǎn) 1 到節(jié)點(diǎn) n n n 的距離即為 3。

算法代碼

  1. 當(dāng)數(shù)據(jù)范圍滿足 1 ≤ n ≤ 500 , 1 ≤ m ≤ 1 0 5 1≤n≤500,1≤m≤10^5 1n500,1m105 時,直接使用樸素算法即可。且圖為稠密圖,結(jié)構(gòu)直接使用鄰接矩陣儲存即可。
#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

const int N = 510;

int g[N][N], d[N];
bool st[N];
int n, m;

int  dijkstra()
{
    memset(d, 0x3f, sizeof d);
    d[1] = 0;
    
    for (int i = 1; i <= n; i ++ )
    {
        int temp = -1;
        for (int j = 1; j <= n; j ++ )
        {
            if (!st[j] && (temp == -1 || d[j] < d[temp])) temp = j;
        }
        
        for (int j = 1; j <= n; j ++ )
        {
            d[j] = min(d[j], d[temp] + g[temp][j]);
        }
        
        st[temp] = true;
    }
    
    if (d[n] == 0x3f3f3f3f) return -1;
    return d[n];
}

int main()
{
    memset(g, 0x3f, sizeof g);
    cin >> n >> m;
    while (m -- )
    {
        int x, y, z;
        cin >> x >> y >> z;
        g[x][y] = min(g[x][y], z);
    }
    cout << dijkstra() << endl;
    return 0;
}

  1. 當(dāng)數(shù)據(jù)范圍滿足 1 ≤ n , m ≤ 1.5 × 1 0 5 1≤n,m≤1.5×10^5 1n,m1.5×105 時,考慮對算法進(jìn)行優(yōu)化。且圖為稀疏圖,所以采用鄰接表存儲結(jié)構(gòu)對圖進(jìn)行儲存。

優(yōu)化:原算法時間復(fù)雜度為 O ( n 2 ) O(n^2) O(n2) ,我們可以發(fā)現(xiàn),如果邊數(shù)遠(yuǎn)小于 n 2 n^2 n2,對此可以考慮用堆這種數(shù)據(jù)結(jié)構(gòu)對其進(jìn)行優(yōu)化,將最耗時的 選取最短路徑過程 的復(fù)雜度降為O(1);此外,使用堆結(jié)構(gòu)后 調(diào)整鄰接點(diǎn)距離過程 的復(fù)雜度變?yōu)? O ( m l o g n ) O(mlogn) O(mlogn);e為該點(diǎn)的邊數(shù),所以復(fù)雜度降為 O ( m l o g n ) O(mlogn) O(mlogn)。
這里使用優(yōu)先隊列 priority_queue 作為堆。文章來源地址http://www.zghlxwxcb.cn/news/detail-406318.html

#include <iostream>
#include <queue>
#include <algorithm>
#include <cstring>

using namespace std;

typedef pair<int, int> PII;

const int N = 2e5;

int n, m, idx = -1;
int h[N], ne[N], w[N], e[N];
int d[N];
bool st[N];

void add(int x, int y, int z)
{
    ne[++ idx] = h[x];
    h[x] = idx;
    e[idx] = y;
    w[idx] = z;
}

int dijkstra()
{
    memset(d, 0x3f, sizeof d);
    d[1] = 0;
    
    priority_queue<PII, vector<PII>, greater<PII>> heap;
    heap.push({0, 1});
    
    while (!heap.empty())
    {
        auto item = heap.top();
        heap.pop();
        
        int dist = item.first, node = item.second;
        
        if (st[node]) continue;
        st[node] = true;
        
        for (int i = h[node]; i != -1; i = ne[i])
        {
            if (d[e[i]] > dist + w[i]) 
            {
                d[e[i]] = dist + w[i];
                heap.push({d[e[i]], e[i]});
            }
        }
    }
    
    if (d[n] == 0x3f3f3f3f) return -1;
    return d[n];
}

int main()
{
    cin >> n >> m;
    memset(h, -1, sizeof h);
    while (m -- )
    {
        int x, y, z;
        cin >> x >> y >> z;
        add(x, y, z);
    }
    cout << dijkstra() << endl;
    return 0;
}

到了這里,關(guān)于(迪杰斯特拉)Dijkstra算法及其優(yōu)化(C++)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • dijkstra迪杰斯特拉算法(鄰接表法)

    dijkstra迪杰斯特拉算法(鄰接表法)

    算法簡易過程: 求單源有向圖最短路徑 使用 鄰接表法 來存儲頂點(diǎn)和邊,錄入 有向圖 。 (當(dāng)然也可以無向圖,不過錄入時要錄入兩次,比如 a b 3? ? ? ? b a 3) ?代碼如下: 測試如下: ?

    2024年02月07日
    瀏覽(33)
  • C語言 最短路徑 迪杰斯特拉(Dijkstra)算法

    C語言 最短路徑 迪杰斯特拉(Dijkstra)算法

    迪杰斯特拉(Dijkstra)算法是由荷蘭計算機(jī)科學(xué)家狄克斯特拉于1959年提出的,因此又叫狄克斯特拉算法。是從一個頂點(diǎn)到其余各頂點(diǎn)的最短路徑算法,解決的是有權(quán)圖中單源最短路徑問題。迪杰斯特拉算法主要特點(diǎn)是從起始點(diǎn)開始,采用貪心算法的策略,每次遍歷到始點(diǎn)距離最

    2024年02月03日
    瀏覽(31)
  • 【數(shù)據(jù)結(jié)構(gòu)】圖解:迪杰斯特拉算法(Dijkstra)最短路徑

    【數(shù)據(jù)結(jié)構(gòu)】圖解:迪杰斯特拉算法(Dijkstra)最短路徑

    目錄 一、方法描述 二、例題一 ??編輯 三、例題二 ?有圖如上,用迪杰斯特拉算法求頂點(diǎn)A到其余各頂點(diǎn)的最短路徑,請問1.第一步求出的最短路徑是A到C的最短路徑2.第二步求出的是頂點(diǎn)A到頂點(diǎn)B/F的最短路徑3.頂點(diǎn)A到D的最短路徑長度是__25___ (填數(shù)字)4.頂點(diǎn)A到頂點(diǎn)F的最短路

    2024年02月12日
    瀏覽(20)
  • java實(shí)現(xiàn)迪杰斯特拉(Dijkstra)算法求解最短路問題

    java實(shí)現(xiàn)迪杰斯特拉(Dijkstra)算法求解最短路問題

    迪杰斯特拉(Dijkstra)算法是由荷蘭計算機(jī)科學(xué)家狄克斯特拉于1959年提出的。是尋找從一個頂點(diǎn)到其余各頂點(diǎn)的最短路徑算法,可用來解決最短路徑問題。 迪杰斯特拉算法采用貪心算法的策略,將所有頂點(diǎn)分為已標(biāo)記點(diǎn)和未標(biāo)記點(diǎn)兩個集合,從起始點(diǎn)開始,不斷在未標(biāo)記點(diǎn)中尋

    2024年02月12日
    瀏覽(30)
  • 大話數(shù)據(jù)結(jié)構(gòu)-迪杰斯特拉算法(Dijkstra)和弗洛伊德算法(Floyd)

    大話數(shù)據(jù)結(jié)構(gòu)-迪杰斯特拉算法(Dijkstra)和弗洛伊德算法(Floyd)

    ??最短路徑,對于圖來說,是兩頂點(diǎn)之間經(jīng)過的邊數(shù)最少的路徑;對于網(wǎng)來說,是指兩頂點(diǎn)之間經(jīng)過的邊上權(quán)值之和最小的路徑。路徑上第一個頂點(diǎn)為源點(diǎn),最后一個頂點(diǎn)是終點(diǎn)。 ??以如下無向圖為例: ??我們來計算下標(biāo)為0的頂點(diǎn),到其他頂點(diǎn)的最短路徑,首先定義

    2024年02月06日
    瀏覽(26)
  • 數(shù)據(jù)結(jié)構(gòu) -最短路徑dijkstra(迪杰斯特拉)算法講解及代碼實(shí)現(xiàn)

    數(shù)據(jù)結(jié)構(gòu) -最短路徑dijkstra(迪杰斯特拉)算法講解及代碼實(shí)現(xiàn)

    ? ? ? ? 迪杰斯特拉算法是一種廣義的貪心算法,求出局部最優(yōu)解,再去求全局最優(yōu)解 舉例圖:(起始點(diǎn)為1) 輔助數(shù)組: s:記錄了目標(biāo)頂點(diǎn)到其他頂點(diǎn)的最短路徑是否求得(求得為1,否則為0) p:目標(biāo)頂點(diǎn)到其他頂點(diǎn)的最短路徑的前驅(qū)節(jié)點(diǎn) (如,求得1-7-5的最短路徑,那

    2024年02月11日
    瀏覽(26)
  • MATLAB輕松繪制地圖路線——Dijkstra(迪杰斯特拉)算法最短路徑規(guī)劃

    MATLAB輕松繪制地圖路線——Dijkstra(迪杰斯特拉)算法最短路徑規(guī)劃

    利用MATLAB繪制地圖需要三個基本數(shù)據(jù): 節(jié)點(diǎn) 節(jié)點(diǎn)坐標(biāo) 節(jié)點(diǎn)間相通的路線 以11B交通巡警平臺調(diào)度問題中的A區(qū)數(shù)據(jù)為例: (數(shù)據(jù)及工程文件下載鏈接見文末) Demo1: 可通過已知節(jié)點(diǎn)的坐標(biāo),計算出各節(jié)點(diǎn)之間的距離,有Matlab基礎(chǔ)的同學(xué)可以嘗試Demo2, 也可通過Excel自行實(shí)現(xiàn);

    2023年04月21日
    瀏覽(23)
  • 數(shù)據(jù)結(jié)構(gòu)與算法 —— 最短路徑Dijkstra算法(迪杰斯特拉)詳細(xì)圖解以及python實(shí)現(xiàn)

    數(shù)據(jù)結(jié)構(gòu)與算法 —— 最短路徑Dijkstra算法(迪杰斯特拉)詳細(xì)圖解以及python實(shí)現(xiàn)

    目錄 前言 1. 介紹 2. 加權(quán)圖 2.1 概念 3. 最短路徑 -- Dijkstra 算法 3.1 歷史 3.2 Dijkstra 算法的基本思路 3.3?Dijkstra 算法圖解 4.? python中dijkstra算法的實(shí)現(xiàn) 5. 總結(jié)? 前兩章我們講到了關(guān)于圖的基本知識,和廣度/深度優(yōu)先搜索。 本章,我們將介紹 加權(quán)圖 和 最短路徑 的相關(guān)知識。 最

    2024年02月12日
    瀏覽(22)
  • 迪杰斯特拉(Dijkstra's )算法——解決帶權(quán)有向無向圖最短路徑

    迪杰斯特拉(Dijkstra's )算法——解決帶權(quán)有向無向圖最短路徑

    迪杰斯特拉算法(Dijkstra\\\'s Algorithm),又稱為狄克斯特拉算法,是一種用于解決帶權(quán)重有向圖或無向圖最短路徑問題的算法。該算法由荷蘭計算機(jī)科學(xué)家艾茲赫爾·狄克斯特拉在1956年發(fā)明,是一種廣泛應(yīng)用于網(wǎng)絡(luò)路由和其他領(lǐng)域的算法。 在 2001 年的一次采訪中,Dijkstra 博士透露

    2024年02月03日
    瀏覽(25)
  • 使用omp并行技術(shù)加速最短路徑算法-迪杰斯特拉(Dijkstra)算法(記錄最短路徑和距離)

    使用omp并行技術(shù)加速最短路徑算法-迪杰斯特拉(Dijkstra)算法(記錄最短路徑和距離)

    原理: Dijkstra算法是解決**單源最短路徑**問題的**貪心算法** 它先求出長度最短的一條路徑,再參照該最短路徑求出長度次短的一條路徑 ? ? 直到求出從源點(diǎn)到其他各個頂點(diǎn)的最短路徑。 首先假定源點(diǎn)為u,頂點(diǎn)集合V被劃分為兩部分:集合 S 和 V-S。 初始時S中僅含有源點(diǎn)u,

    2024年02月10日
    瀏覽(55)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包