日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

最短路[Dijkstra和堆优化的Dijkstra][Bellman-Ford和SPFA][Floyd最短路](更新中)

發布時間:2025/4/5 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 最短路[Dijkstra和堆优化的Dijkstra][Bellman-Ford和SPFA][Floyd最短路](更新中) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • 第一類:單源最短路
        • 一 所有邊權都是正數(Dijkstra)
          • 樸素版Dijkstra(稠密圖)
          • 堆優化版Dijkstra(稀疏圖)
        • 二 存在負權邊(BF和SPFA)
    • 第二類:多源匯最短路(Floyd)

常見的最短路問題,假定邊為m,頂點為n。

第一類:單源最短路

一個點到其他所有點的最短距離,比如:從1到n的最短路
單源最短路再分兩種:

一 所有邊權都是正數(Dijkstra)

兩種算法:
樸素Dijkstra算法,時間復雜度O(n2)O(n^2)O(n2),和邊的數量無關,適合于稠密圖(邊數很多,m和n2n^2n2是一個規模)。
堆優化的Dijstra算法。 時間復雜度O(mlogn)O(mlogn)O(mlogn),適合于稀疏圖。
其中,n是圖中點的數量,m是圖中邊的數量

Dijkstra算法的思想是基于貪心的,每次選擇最短的路。

樸素Dijkstra算法步驟:

集合S表示已確定最短距離的點

1. dist[1]=0,dist[i]= INF //初始化 2. for i: 1~nt ?不在S中的距離最近的點S ? t用t更新其他點的距離
樸素版Dijkstra(稠密圖)

Acwing849. Dijkstra求最短路 I(稠密圖)
給定一個n個點m條邊的有向圖,圖中可能存在重邊和自環,所有邊權均為正值。

請你求出1號點到n號點的最短距離,如果無法從1號點走到n號點,則輸出-1。

輸入格式
第一行包含整數n和m。

接下來m行每行包含三個整數x,y,z,表示存在一條從點x到點y的有向邊,邊長為z。

輸出格式
輸出一個整數,表示1號點到n號點的最短距離。

如果路徑不存在,則輸出-1。

數據范圍
1≤n≤500,
1≤m≤105,
圖中涉及邊長均不超過10000。

輸入樣例:
3 3
1 2 2
2 3 1
1 3 4
輸出樣例:
3

ac代碼

#include<bits/stdc++.h> using namespace std; const int N=510;int m , n; int g[N][N];bool st[N]; //該點是否確定最短路 int dist[N];//原點到各點的距離 int dijkstra(){memset(dist,0x3f3f3f,sizeof(dist)); //初始化距離無窮大dist[1] =0 ; //1號點初始化為0//迭代n次 for(int i=0;i<n;i++){//找最小值int t=-1; //找到當前最小的值 用t來存,t=-1表示沒找到 for(int j=1;j<=n;j++){if(!st[j]&&( t==-1 || dist[t] >dist[j] ))t=j;} //加到集合S中st[t]=true;//用t更新其他點的距離for(int j=1;j<=n;j++)dist[j]= min(dist[j],dist[t]+g[t][j]); } //如果不連通返回-1if(dist[n]>=0xffff) return -1;return dist[n]; }int main(){cin>>n>>m;memset(g,0x3f,sizeof g);while(m--){int a,b,c;cin>>a>>b>>c;g[a][b]=min(g[a][b],c); //去除重邊 } int t=dijkstra();cout<<t<<endl;}
堆優化版Dijkstra(稀疏圖)

acwing850. Dijkstra求最短路 II

給定一個n個點m條邊的有向圖,圖中可能存在重邊和自環,所有邊權均為非負值。

請你求出1號點到n號點的最短距離,如果無法從1號點走到n號點,則輸出-1。

輸入格式
第一行包含整數n和m。

接下來m行每行包含三個整數x,y,z,表示存在一條從點x到點y的有向邊,邊長為z。

輸出格式
輸出一個整數,表示1號點到n號點的最短距離。

如果路徑不存在,則輸出-1。

數據范圍
1≤n,m≤1.5×1051≤n,m≤1.5×10^51n,m1.5×105,
圖中涉及邊長均不小于0,且不超過10000。

輸入樣例:
3 3
1 2 2
2 3 1
1 3 4
輸出樣例:
3

分析:

這題是稀疏圖,使用鄰接表來存儲。

ac代碼

#include<bits/stdc++.h> using namespace std; const int Mn=1e9;const int N=1000000;typedef pair<int ,int > PII;bool st[N]; //是否確定最短路 int dist[N]; //最短距離 int n ,m; //使用鄰接表來存儲圖 int h[N]; // 頭節點數組 int ne[N]; //next指針指向的地址,這里是結點b的地址 int e[N]; //next指針指向的具體的值,這里是結點b int w[N]; // a到b的邊的權重 int idx; //索引//加邊 a后面加b,權重是c void add(int a,int b,int c){e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++; }int dijkstra(){memset(dist,0x3f,sizeof dist);dist[1]=0;priority_queue<PII,vector<PII> ,greater<PII>> heap; heap.push({0,1}); //距離為0,編號為1 之所以距離放前面,是因為heap按照第一關鍵字排序while(heap.size()){//找最小點auto t=heap.top();heap.pop();int ver =t.second, distance = t.first; //ver是編號,distance 是距離if(st[ver]) continue;//找到最小值st[ver]=true; //用當前點更新其他點//遍歷當前 點ver的相鄰的點for(int i=h[ver];i!=-1;i = ne[i]){int j=e[i]; //點if(dist[j]> distance + w[i]){dist[j]= distance +w[i];heap.push({dist[j],j});}}}if(dist[n]>=Mn) return -1;return dist[n];}int main(){cin>>n>>m;memset(h ,-1 ,sizeof h); //頭結點數組初始化為-1while(m--){int a , b, c;cin>>a>>b>>c;add(a,b,c); //鄰接表}int t=dijkstra();cout<<t<<endl;}

二 存在負權邊(BF和SPFA)

兩種算法:假定邊為m,頂點為n
Bellman-Ford算法 ,時間復雜度O(nm)O(nm)O(nm),適合于邊數不超過k條(此處k為限定的邊數)。

算法思路:

  • 掃描所有邊(x, y, z),這里指的是從x到y,邊權為z的邊 ,如果dist[y] > dist[x] + z, 則用dist[x] + z 更新dist[y].
  • 重復上述步驟,直到沒有更新操作發生。
  • 而spfa算法呢,在國際上通常稱為”隊列優化的Bellman-Ford算法“。它是對Bellman-Ford算法的優化,一般而言,我們刷題用的多的還是spfa。

    SPFA算法 一般情況下比Bellman-Ford快,時間復雜度O(m)O(m)O(m),最壞O(nm)O(nm)O(nm),適合于負權邊

    spfa算法流程:

  • 建立一個隊列,最初隊列中只含有起點1
  • 取出隊頭結點x,掃描它的所有出邊(x, y, z),如果dist[y] > dist[x] + z, 則用dist[x] + z 更新dist[y].同時, 若y不在隊列中,則把y入隊。
  • 重復上述步驟,直到隊列為空。
  • 851. spfa求最短路

    來源:acwing

  • spfa代碼和堆優化dijkstra很像。只不過spfa用的是隊列queue。關于queue的操作,取出隊頭元素是front();存入元素是push().當然建圖同樣是鄰接表。
  • spfa算法中st數組的含義是:某個點是否已經在隊列中。
  • spfa算法模板代碼

    #include<bits/stdc++.h> #define x first #define y second using namespace std; const int N = 1e5 + 10; int n, m; int h[N],ne[N],w[N],e[N], idx; typedef pair<int,int> PII;int dist[N]; bool st[N]; // st數組存的是當前這個點是否在隊列中void add(int a, int b, int c){e[idx] = b, w[idx] = c, ne[idx] = h[a] ,h[a] = idx ++; }int spfa(){memset(dist, 0x3f, sizeof dist);dist[1] = 0;queue<int> q;q.push(1); // 把1號點放進隊列st[1] = true; while(q.size()){int t = q.front();q.pop();st[t] = false; // 從隊列中出來for(int i = h[t]; i != -1; 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;}}}}if(dist[n] == 0x3f3f3f3f) return -1;return dist[n];}int main(){cin >> n >> m;memset(h, -1, sizeof h);while(m --){int a, b, c;cin >> a >> b >> c;add(a, b ,c );}int t = spfa();if( t == -1) puts("impossible");else cout << t << endl;}

    補充手寫隊列的spfa寫法:

    int spfa(){memset(dist, 0x3f, sizeof dist);int hh = 0, tt = 0;q[0] = 1;dist[1] = 0;st[1] = true;while(hh <= tt){auto t = q[ hh ++];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[ ++ tt] = j;st[j] = true;}}}}if(dist[n] == 0x3f3f3f3f) return -1;return dist[n]; }

    第二類:多源匯最短路(Floyd)

    源點:起點;匯點:終點;
    假定邊為m,頂點為n
    任選兩個點,從其中一個點到另外一個點的最短距離。即起點和終點不確定。很多不同起點到其他點的最短路
    算法 :Floyd 算法, 時間復雜度O(n3)O(n^3)O(n3)

    考察側重點:建圖。

    可以用有向圖的算法直接解決無向圖的問題。

    總結

    以上是生活随笔為你收集整理的最短路[Dijkstra和堆优化的Dijkstra][Bellman-Ford和SPFA][Floyd最短路](更新中)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 国产精品av一区 | 亚洲一区二区三区加勒比 | 国产成人+综合亚洲+天堂 | 91福利在线观看视频 | 人人插人人看 | 午夜影院在线观看18 | 久国产 | 亚洲精品人人 | 日日摸天天爽天天爽视频 | 91男女视频 | 五月天男人天堂 | 88久久精品无码一区二区毛片 | 午夜网站在线观看 | 亚洲制服丝袜一区 | 亚洲hh| 成人做爰免费视频免费看 | va婷婷在线免费观看 | 亚洲一一在线 | 久久久久久久国产精品 | 五月天综合激情网 | 日本黄色录相 | 丝袜美腿av | 日本毛片在线看 | 国产绿帽刺激高潮对白 | 欧美精品一区二区久久婷婷 | 女色婷婷 | 国产美女极度色诱视频www | 成人在线观看免费视频 | 久操久操 | 91天天操 | 国产一区免费在线观看 | 亚洲最大福利网站 | 二区视频在线观看 | 香蕉视频黄色在线观看 | 亚洲成人高清在线观看 | 亚洲国产av一区二区 | 国产麻豆一区二区三区在线观看 | 欧美成人三级在线观看 | 久久综合激情网 | 久久久久久久国产精品 | 亚洲精品国产欧美在线观看 | 蜜桃臀aⅴ精品一区二区三区 | 亚洲一区二区伦理 | 国产亚洲精品自拍 | 国产不卡一区二区视频 | 91精品国产综合久久香蕉922 | 福利在线看 | 射死你天天日 | 国产成人在线精品 | 在线免费视频一区 | 99精品免费观看 | 亚洲一二三四在线观看 | 日本一区二区三区免费看 | 一区二区在线视频播放 | 欧美无砖区 | 老熟妇仑乱一区二区av | 色播欧美 | 亚洲香蕉网站 | 秋霞成人午夜鲁丝一区二区三区 | 精品一区在线观看视频 | 国产精品久久久久永久免费看 | 久艹视频在线观看 | 亚洲激情视频在线观看 | 欧美日韩一二三 | 少妇人妻邻居 | 日本黄网站色大片免费观看 | 狠狠躁日日躁夜夜躁2022麻豆 | 国产精品 色 | 人人草人人澡 | 中文字幕一区二区三区人妻不卡 | 精品一区二区日韩 | 公交顶臀绿裙妇女配视频 | 干干操操| 色av免费| 好屌妞视频这里有精品 | 毛片日本 | 日韩免费福利 | 四虎精品欧美一区二区免费 | 少妇喷水在线观看 | 精品久久久久久亚洲综合网站 | 丰满少妇被猛烈进入一区二区 | 欧美一级久久 | 黄色www视频 | 亚洲天堂av一区二区三区 | 片黄在线观看 | 一区二区三区天堂 | 亚洲一区中文 | 长河落日电视连续剧免费观看 | 午夜精品久久 | 99精品一级欧美片免费播放 | 女同在线视频 | 色八区| www.四色| 50部乳奶水在线播放 | 国产精品久久久精品三级 | 亚洲综合色成人 | 成人av电影在线播放 | 白洁av| 国产男女猛烈无遮挡免费视频 |