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

【算法入門&圖論】【模板】拓撲排序|【模板】單源最短路2 |最小生成樹

這篇具有很好參考價值的文章主要介紹了【算法入門&圖論】【模板】拓撲排序|【模板】單源最短路2 |最小生成樹。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

?作者簡介:熱愛后端語言的大學(xué)生,CSDN內(nèi)容合伙人
?精品專欄:C++面向?qū)ο?/strong>
??系列專欄:算法百煉成神


??前言

本專欄收錄的均為??途W(wǎng)的算法題目,內(nèi)含鏈表、雙指針、遞歸、動態(tài)規(guī)劃、基本數(shù)據(jù)結(jié)構(gòu)等算法思想的具體運用。??途W(wǎng)不僅有大量的經(jīng)典算法題目,也有大廠的面試真題,面試、找工作完全可以來這里找機會。此外,網(wǎng)站內(nèi)的編碼主題多樣化,調(diào)試功能可運用性強,可謂是非常注重用戶體驗。這么好的免費刷題網(wǎng)站還不快入手嗎,快去注冊開啟算法百煉成神之路吧!

1、AB13 【模板】拓撲排序

學(xué)會使用鄰接表解決圖論問題,巧妙利用vector容器

題目鏈接:拓樸排序

ab15 【模板】單源最短路2,# 經(jīng)典算法的C++實現(xiàn),算法,圖論,數(shù)據(jù)結(jié)構(gòu)

1.1、解題思路

解決拓撲排序之前要先認識什么是拓撲排序:

對一個有向無環(huán)圖(Directed Acyclic Graph簡稱DAG)圖G進行拓撲排序,是將G中所有頂點排成一個線性序列,使得圖中任意一對頂點uv,若邊<u,v>∈E(G),則u在線性序列中出現(xiàn)在v之前。通常,這樣的線性序列稱為滿足拓撲次序(Topological Order)的序列,簡稱拓撲序列。簡單的說,由某個集合上的一個偏序得到該集合上的一個全序,這個操作稱之為拓撲排序。

解決步驟:

  1. 使用鄰接表將頂點聯(lián)系起來,輔助數(shù)組inDegree表示每個頂點的入度。
  2. 借助隊列和計數(shù)器變量來判斷該有向圖是否有環(huán):
    • 將入度為零的頂點入隊(也就是拓撲圖第一個頂點)
    • 取隊首,遍歷與之相鄰的頂點,若該頂點入度減一后為零就將其入隊
    • 只要隊列非空就循環(huán)操作,計算器循環(huán)加一,與頂點數(shù)比較是否相等
  3. 本題末尾也不能輸出空格,因此輸出拓撲序列時要加限制條件

1.2、代碼實現(xiàn)與注釋

本題源碼:

#include<iostream>
#include<vector>
#include<queue>
#define M 200001
using namespace std;

int main() {
    int n, m;
    cin >> n >> m;
    vector<int> adjList[M]; // 模擬鄰接表
    int inDegree[M] = { 0 };// 記錄每個頂點的入度
    int a, b;
    for (int i = 0; i < m; i++) {
        cin >> a >> b;
        adjList[a].push_back(b);
        inDegree[b]++;
    }
    queue<int> que; // 將初始入度為零的頂點入隊
    for (int i = 1; i <= n; i++) {
        if (inDegree[i] == 0)
            que.push(i);
    }

    int cnt = 0; // 用來計數(shù),判斷改圖是否有環(huán)
    vector<int> res; // 用來輸出頂點序列
    while (!que.empty()) {
        int u = que.front();
        que.pop();
        res.push_back(u);
        for (int i = 0; i < adjList[u].size(); i++) { // 遍歷u的相鄰頂點
            int v = adjList[u][i];
            if (--inDegree[v] == 0)
                que.push(v);
        }
        cnt++;
    }
    // 若計數(shù)器與頂點數(shù)相同則圖無環(huán),存在拓撲排序
    if (cnt == n) {
        for (int i = 0; i < res.size(); i++) {
            cout << res[i];
            // 限制輸出空格的條件
            if (i != res.size() - 1) {
                cout << " ";
            }
        }
    } else {
        cout << -1;
    }
    return 0;
}

重要注釋:

  • adjList數(shù)組是vector類型的,用來模擬鄰接表
    • 使用每個元素為一個數(shù)組的vector容器模擬鄰接表進行建圖
    • vector[a]所對應(yīng)的數(shù)組中存儲著該頂點所指向的其他頂點
    • inDegree數(shù)組代表每一個頂點的入度情況
  • 使用一個隊列,初始時將所有入度為0的頂點全部入隊,之后采用BFS的思想:
    • 依次取出隊頭元素并存入結(jié)果數(shù)組中,然后在鄰接表中遍歷該隊頭元素所指向的其他頂點
    • 將這些頂點的入度全部減一,若減一后某頂點的入度變?yōu)?,則將該頂點進行入隊操作,
      重復(fù)此步驟直至隊列為空為止。
  • 設(shè)置一個用于判斷圖中是否存在環(huán)(是否可以得到拓撲序列)的計數(shù)器,在彈出隊頭元素后要將計數(shù)器加一,最后隊列為空后,若計數(shù)器的值與頂點數(shù)相同,則說明圖不存在環(huán),可以得到拓撲序列。

2、AB14 最小生成樹

題目鏈接:最小生成樹

ab15 【模板】單源最短路2,# 經(jīng)典算法的C++實現(xiàn),算法,圖論,數(shù)據(jù)結(jié)構(gòu)

2.1、解題思路

本題要求在最小花費下將 n 戶人家連接起來,很顯然是最小生成樹的問題,我采用prim算法:

  1. 將二維數(shù)組cost按權(quán)升序排序,那么cost[0][2]就是最小的一個權(quán)值
  2. 將連接這條邊的兩個頂點放入unordered_set容器:
    • unordered_set 容器的元素是無序的,可以用來給頂點去重
    • 內(nèi)置的 find 方法也很好用
  3. 接下來遍歷cost二維數(shù)組,直到所有頂點全部放入容器中,遍歷結(jié)束
  4. 將遍歷中權(quán)值的和返回,程序結(jié)束

2.2、代碼實現(xiàn)與注釋

本題源碼:

class Solution {
  public:
    /**
     * 代碼中的類名、方法名、參數(shù)名已經(jīng)指定,請勿修改,直接返回方法規(guī)定的值即可
     *
     * 返回最小的花費代價使得這n戶人家連接起來
     * @param n int n戶人家的村莊
     * @param m int m條路
     * @param cost intvector<vector<>> 一維3個參數(shù),表示連接1個村莊到另外1個村莊的花費的代價
     * @return int
     */

    // 自定義排序規(guī)則:按權(quán)遞增
    static bool cmp(vector<int>& x, vector<int>& y) {
        return x[2] < y[2];
    }
    int miniSpanningTree(int n, int m, vector<vector<int> >& cost) {
        unordered_set<int> points; // 記錄不重復(fù)的點
        int res = 0;
        sort(cost.begin(), cost.end(), cmp);
        res += cost[0][2]; // 此時res 為最小權(quán)值
        // 將最小邊加入
        points.insert(cost[0][0]);
        points.insert(cost[0][1]);
        while (1) {
            if (points.size() == n)
                break; // 所有的點連同后退出循環(huán)
            // 遍歷剩余的邊
            for (auto it = cost.begin(); it != cost.end(); it++) {
                // 如果邊僅有一個點在集合內(nèi)就加入
                if ((points.find((*it)[0]) != points.end() &&
                    points.find((*it)[1]) == points.end()) ||
                    (points.find((*it)[1]) != points.end() &&
                    points.find((*it)[0]) == points.end()))
                    {
                        res += (*it)[2];
                        points.insert((*it)[0]);
                        points.insert((*it)[1]);
                        cost.erase(it); // 刪除該邊
                        break;
                    }
            }
        }
        return res;
    }
};

重要注釋:

  • cmp 是自定義的一個按權(quán)遞增的排序函數(shù),配合sort函數(shù)來將cost排序
    • 相關(guān)知識點可以參考我的博文:自定義排序規(guī)則
  • auto關(guān)鍵字可以自動推導(dǎo)表達式類型,在這里就相當于vector<vector<int>>::iterator
  • if的條件很長,但其實就是將有且僅有一個頂點在points中的邊找到:
    • 獲取該邊的權(quán)值并求和,將另一頂點插入到points
    • 將該邊刪除,重新遍歷cost,直到全部頂點被插入到points
  • 最終的 res 就是該題的結(jié)果,即最小花費。

3、AB15 單源最短路2

題目鏈接:單源最短路2

ab15 【模板】單源最短路2,# 經(jīng)典算法的C++實現(xiàn),算法,圖論,數(shù)據(jù)結(jié)構(gòu)ab15 【模板】單源最短路2,# 經(jīng)典算法的C++實現(xiàn),算法,圖論,數(shù)據(jù)結(jié)構(gòu)

3.1、解題思路

使用Dijkstra算法(即不斷從未處理集合中找當前距離源點最近的頂點以添加到已處理集合中,直至未處理集合為空的算法思想)

  1. 對于無向圖,采用鄰接矩陣表示點與點的連接關(guān)系以及距離
  2. 使用數(shù)組dist記錄每個頂點與源點的距離:
    • 本題中就是記錄頂點1與其他頂點的距離
  3. 用一個布爾類型的數(shù)組記錄頂點的處理情況:
    • 初始狀態(tài)全部設(shè)為false,一經(jīng)處理就設(shè)為true
  4. 最終dist[n]就是頂點n到源點的最短距離

3.2、代碼實現(xiàn)與注釋

本題源碼

#include<iostream>
#include<climits> // 使用INT_MAX所需要引入的頭文件
using namespace std;
const int N = 5000; // 注意題干,圖的點數(shù)是固定值5000

int main() {

    int G[N + 1][N + 1]; // 用于模擬鄰接矩陣進行建圖
    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= N; j++) {
            G[i][j] = INT_MAX; // 先將鄰接矩陣全部初始化為無窮大
        }
    }
    int n, m;
    cin >> n >> m;
    int u, v, w;
    for (int i = 1; i <= m; i++) {
        cin >> u >> v >> w;
        G[u][v] = w;
        G[v][u] = w; // 需要關(guān)于主對角線對稱,因此兩邊都需要存儲
    }
    int dist[N + 1]; // 用于存儲每個頂點當前與源點的最短距離

    bool flag[N + 1]; // 用于記錄每個頂點是否已經(jīng)完成與源點最短距離的計算處理

    for (int i = 1; i <= N; i++) {
        dist[i] = G[1][i]; // 初始設(shè)置為鄰接矩陣中源點所在 行 的權(quán)值
        flag[i] = false;
    }
    
    dist[1] = 0;
    flag[1] = true; // 將源點加入已處理集合
    
    for (int i = 2; i <= N; i++) {
        int tmp = INT_MAX, index = 1;
        for (int j = 1; j <= N; j++) { // 遍歷尋找與源點的最短距離
            if (flag[j] == false && dist[j] < tmp) {
                tmp = dist[j];
                index = j;
            }
        }
        if (index != 1) {
            flag[index] = true; // 找到后將其加入已處理集合
        }
        for (int j = 2; j <= N; j++) {
            if (flag[j] == false && G[index][j] != INT_MAX) {
                if (G[index][j] + dist[index] < dist[j]) {
                    dist[j] = G[index][j] + dist[index]; // 更新最短路徑
                }
            }
        }
    }
    if (dist[n] != INT_MAX) {
        cout << dist[n];
    } else {
        cout << -1;
    }
    return 0;
}

重要注釋:

  • 二維數(shù)組G是具化出的鄰接矩陣,將元素值全部初始化為無窮大:INT_MAX
  • u,v記錄兩個頂點,w記錄頂點間距離,全部存入G
  • dist數(shù)組用來存放各頂點到源點的距離,flag數(shù)組記錄頂點是否被處理過
  • index代表著與源點連接且距離最短的未經(jīng)處理的頂點:
    • 隨后將該頂點設(shè)為已處理
  • 然后index尋找與之相連且未經(jīng)處理的頂點:
    • dist[index]index到源點的最短距離,如果加上與之相連的頂點的距離較小,那么就更新最短路徑
  • 最終的dist數(shù)組的值就是各點到源點的最短路徑

當自己動手去做的時候才發(fā)現(xiàn)原來我以為的難題,不過如此,將這份自信傳達給大家,奮斗下去!文章來源地址http://www.zghlxwxcb.cn/news/detail-780658.html

到了這里,關(guān)于【算法入門&圖論】【模板】拓撲排序|【模板】單源最短路2 |最小生成樹的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • 【圖論】單源最短路

    【圖論】單源最短路

    算法提高課筆記 最短路問題可以分為以下兩類: 邊權(quán)非負——樸素Dijkstra、堆優(yōu)化Dijkstra 有負權(quán)邊——Bellman-Ford、SPFA 熱浪 原題鏈接 德克薩斯純樸的民眾們這個夏天正在遭受巨大的熱浪?。?! 他們的德克薩斯長角牛吃起來不錯,可是它們并不是很擅長生產(chǎn)富含奶油的乳制品

    2024年02月14日
    瀏覽(21)
  • 【圖論】單源最短路問題

    Dijkstra算法是一種單源最短路徑算法,用于找出圖中從一個源點到其他所有點的最短路徑。該算法的原理是采用貪心策略,每次將距離源點最近的點加入到已確定最短路徑的集合中,并更新其它節(jié)點的距離。具體實現(xiàn)過程如下: 初始化距離數(shù)組dist[],源點距離為0,其余點距離

    2024年02月13日
    瀏覽(18)
  • 【算法入門&搜索法】走迷宮|單源最短路徑1

    【算法入門&搜索法】走迷宮|單源最短路徑1

    ?作者簡介:熱愛后端語言的大學(xué)生,CSDN內(nèi)容合伙人 ?精品專欄:C++面向?qū)ο???系列專欄:算法百煉成神 本專欄收錄的均為??途W(wǎng)的算法題目,內(nèi)含鏈表、雙指針、遞歸、動態(tài)規(guī)劃、基本數(shù)據(jù)結(jié)構(gòu)等算法思想的具體運用。牛客網(wǎng)不僅有大量的經(jīng)典算法題目,也有大廠的面

    2024年02月03日
    瀏覽(23)
  • 【圖論 單源最短路】100276. 最短路徑中的邊

    【圖論 單源最短路】100276. 最短路徑中的邊

    單源最短路 圖論知識匯總 給你一個 n 個節(jié)點的無向帶權(quán)圖,節(jié)點編號為 0 到 n - 1 。圖中總共有 m 條邊,用二維數(shù)組 edges 表示,其中 edges[i] = [ai, bi, wi] 表示節(jié)點 ai 和 bi 之間有一條邊權(quán)為 wi 的邊。 對于節(jié)點 0 為出發(fā)點,節(jié)點 n - 1 為結(jié)束點的所有最短路,你需要返回一個長度

    2024年04月22日
    瀏覽(24)
  • 【單源最短路 圖論】882. 細分圖中的可到達節(jié)點

    【單源最短路 圖論】882. 細分圖中的可到達節(jié)點

    視頻算法專題 單源最短路 圖論 給你一個無向圖(原始圖),圖中有 n 個節(jié)點,編號從 0 到 n - 1 。你決定將圖中的每條邊 細分 為一條節(jié)點鏈,每條邊之間的新節(jié)點數(shù)各不相同。 圖用由邊組成的二維數(shù)組 edges 表示,其中 edges[i] = [ui, vi, cnti] 表示原始圖中節(jié)點 ui 和 vi 之間存在

    2024年04月10日
    瀏覽(26)
  • 第三章 圖論 No.1單源最短路及其綜合應(yīng)用

    第三章 圖論 No.1單源最短路及其綜合應(yīng)用

    做乘法的最短路時,若權(quán)值=0,只能用spfa來做,相等于加法中的負權(quán)邊 1129. 熱浪 1129. 熱浪 - AcWing題庫 單源最短路,稀疏圖,用堆優(yōu)化Dijkstra即可,就是板子套了個背景 debug:由于是無向圖,邊的數(shù)量要開兩倍。但是 w[N] 沒改,debug了很久 所以 e[M], ne[M], w[M] ,只有 h[N] ,其他

    2024年02月14日
    瀏覽(19)
  • 第三章 圖論 No.2單源最短路之虛擬源點,狀壓最短路與最短路次短路條數(shù)

    第三章 圖論 No.2單源最短路之虛擬源點,狀壓最短路與最短路次短路條數(shù)

    dp是特殊的最短路,是無環(huán)圖(拓撲圖)上的最短路問題 1137. 選擇最佳線路 1137. 選擇最佳線路 - AcWing題庫 對于每組測試數(shù)據(jù),該重置的數(shù)據(jù)要重置,我沒有重置idx,導(dǎo)致TLE 處理反向建圖,還有一種擴展做法:虛擬源點 設(shè)置虛擬源點,與每個起點之間連接邊權(quán)為0的邊 原問題

    2024年02月14日
    瀏覽(27)
  • 【算法】單源最短路徑算法——Dijkstra算法

    【算法】單源最短路徑算法——Dijkstra算法

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

    2024年02月05日
    瀏覽(26)
  • 數(shù)據(jù)結(jié)構(gòu)學(xué)習(xí)記錄——圖-最短路徑問題(無權(quán)圖單源最短路徑算法、有權(quán)圖單源最短路徑算法、多源最短路徑算法、Dijkstra(迪杰斯特拉)算法、Floyd算法)

    數(shù)據(jù)結(jié)構(gòu)學(xué)習(xí)記錄——圖-最短路徑問題(無權(quán)圖單源最短路徑算法、有權(quán)圖單源最短路徑算法、多源最短路徑算法、Dijkstra(迪杰斯特拉)算法、Floyd算法)

    目錄 問題分類? 無權(quán)圖單源最短路徑算法 思路 偽代碼 時間復(fù)雜度 代碼實現(xiàn)(C語言) 有權(quán)圖單源最短路徑算法 Dijkstra(迪杰斯特拉)算法 偽代碼? 時間復(fù)雜度? 代碼實現(xiàn)(C語言) 多源最短路徑算法 兩種方法 Floyd算法 代碼實現(xiàn)(C語言) 最短路徑問題的抽象 在網(wǎng)絡(luò)中,求

    2024年02月08日
    瀏覽(22)
  • C++算法:單源最短路徑Dijkstra

    C++算法:單源最短路徑Dijkstra

    如果你有一份北京地圖,想從中關(guān)村走到三元橋,那么怎樣能找出實現(xiàn)這一目的的最短路徑呢?一種可能的方法就是將這兩點之間所有的路線都找出來,然后求出每條路線的距離,找出最短的路線。但是仔細想想我們就會發(fā)現(xiàn)這種辦法幾乎是不可行的,因為這樣的路線太多了,

    2024年02月09日
    瀏覽(24)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包