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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

最短路径之spfa

發布時間:2025/5/22 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 最短路径之spfa 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

引入1:單源最短路

問:求帶權有向圖上一個源點到其他點的最短路徑距離

如果沒有非負邊權,我們自然可以想到dij。但是如果有負邊權呢?這時候就要用SPFA算法求解。

原理&講解

用dis數組記錄源點到有向圖上任意一點距離,其中源點到自身距離為0,到其他點距離為INF。將源點入隊,并重復以下步驟:

  • 隊首x出隊
  • 遍歷所有以隊首為起點的有向邊(x,i),若dis[x]+w(x,i)<dis[i],則更新dis[i]
  • 如果點i不在隊列中,則i入隊
  • 若隊列為空,跳出循環;否則執行1

實際上我們可以將其理解為bfs

如果圖是隨機生成的,時間復雜度為 O(KM) (K可以認為是個常數,m為邊數,n為點數)

但是實際上SPFA的算法復雜度是 O(NM) ,可以構造出卡SPFA的數據,讓SPFA超時。

在NOI 2018的第一天第一題中,出題人卡了SPFA算法,導致100分變成60分,所以在沒有負環、單純求最短路徑,不建議使用SPFA算法,而是用Dijkstra算法。

在初一我們學到一條三角形中的性質,即同一三角形內兩邊之和大于第三邊。而最短路中如u->v的最短路它是小于等于其它任意路徑的,這使我們容易yy到三角形。也就是說,我們實際上每次都是在判斷這條路徑符不符合三角形不等式,若不符合,我們就將原先的路徑松弛為現在的路徑,使得現在的路徑滿足三角形不等式。但是為什么松弛后要將終點入隊呢?SPFA的過程是BFS,它是不停擴展節點的。而當我們更新了這一條路徑,那么可能會出現基于這一條路徑的新路,我們需要判斷原路與新路是否滿足三角形不等式。

模擬&代碼

我們可以手推這張圖模擬一下~

我們以1為源點,初始化:dis[源點]=0,其他為正無窮,并將源點入隊。

隊首1出隊,并枚舉它的出邊1->2,1->3。由dis[1]+w(1,2)=1<dis[2]=INF,dis[1]+w(1,3)=6<dis[3]=INF得dis[2]=dis[1]+w(1,2)=1,dis[3]=dis[1]+w(1,3)=6,并將2,3入隊。

隊首2出隊,枚舉它的出邊2->3,2->4,2->5。都不滿足三角形不等式,所以松弛它們。并將3,4,5入隊,但由于3已在隊內,所以不管。

隊首3出隊,沒有能松弛的邊,直接略過。

此時隊內剩下4,5,由于這兩點沒有出邊,所以在此不枚舉。

手繪勿噴

下面是帶注釋代碼:

#include<iostream> #include<vector> #include<algorithm> #include<cstring> #include<string> #include<cstdio> #include<cstdlib> #include<queue> #define N 110000 #define INF 0x3f3f3f3f using namespace std;int n,m,a,b,c,vis[N],dis[N];struct node {int d,w; };//定義一個結構體來存儲每個入度點以及對應邊的權值 //比如邊u->v,權值為w,node結構體存儲的就是v以及w。vector<node>v[N];void spfa(int u);int main() {//對于N非常大但是M很小的這種稀疏圖來說,用鄰接矩陣N*N是存不下的。鄰接矩陣是將所有的點都存儲下來了,然而//對于稀疏圖來說,有很多點是沒有用到的,把這些點也存儲下來的話就會很浪費空間。可以用鄰接表來存儲,這里借助vector來實現鄰接表的操作。//用鄰接表存儲時候,只存儲有用的點,對于沒有用的點不存儲,實現空間的優化。cin>>n>>m;for(int i=0; i<=n; i++)v[i].clear();//將vecort數組清空for(int i=1; i<=m; i++) //用vector存儲鄰接表{node nd;scanf("%d%d%d",&a,&b,&c);nd.d=b,nd.w=c;//將入度的點和權值賦值給結構體v[a].push_back(nd);//將每一個從a出發能直接到達的點都壓到下標為a的vector數組中,以后遍歷從a能到達的點就可以直接遍歷v[a]// nd.d=a,nd.w=c;//無向圖的雙向存邊// v[b].push_back(nd);}spfa(1);if(dis[n]!=INF)printf("%d\n",dis[n]);elseprintf("impossible");return 0; } void spfa(int u){memset(vis,1,sizeof(vis));memset(dis,0x3f,sizeof(dis));dis[u]=0;queue<int> q;q.push(u);vis[u]=false;while (!q.empty()) {int x=q.front();q.pop();vis[x]=true;vector<node> s=v[x];for (int i = 0; i < s.size(); ++i) {int v=s[i].d;if(dis[x]+s[i].w<dis[v]){dis[v]=dis[x]+s[i].w;if(vis[v]){q.push(v);vis[v]=false;}}}} }

引入2:判正(負)環

spfa算法還可以在有向圖內判正環負環,我們可以使用DFS/BFS版SPFA。注意,判負環跑最短路,判正環跑最長路。

#include<iostream> #include<vector> #include<algorithm> #include<cstring> #include<string> #include<cstdio> #include<cstdlib> #include<queue> #define N 110000 #define INF 0x3f3f3f3f using namespace std;int n,m,a,b,c,instack[N],dis[N],flag;struct node {int d,w; };//定義一個結構體來存儲每個入度點以及對應邊的權值 //比如邊u->v,權值為w,node結構體存儲的就是v以及w。vector<node>v[N];void spfa(int u);int main() {//對于N非常大但是M很小的這種稀疏圖來說,用鄰接矩陣N*N是存不下的。鄰接矩陣是將所有的點都存儲下來了,然而//對于稀疏圖來說,有很多點是沒有用到的,把這些點也存儲下來的話就會很浪費空間。可以用鄰接表來存儲,這里借助vector來實現鄰接表的操作。//用鄰接表存儲時候,只存儲有用的點,對于沒有用的點不存儲,實現空間的優化。cin>>n>>m;for(int i=0; i<=n; i++)v[i].clear();//將vecort數組清空for(int i=1; i<=m; i++) //用vector存儲鄰接表{node nd;scanf("%d%d%d",&a,&b,&c);nd.d=b,nd.w=c;//將入度的點和權值賦值給結構體v[a].push_back(nd);//將每一個從a出發能直接到達的點都壓到下標為a的vector數組中,以后遍歷從a能到達的點就可以直接遍歷v[a]// nd.d=a,nd.w=c;//無向圖的雙向存邊// v[b].push_back(nd);}memset(instack,0,sizeof(instack));memset(dis,0,sizeof(dis));flag=0;for(int i=1;i<=n;i++){spfa(i);if(flag)break;}if(flag)printf("Yes");else printf("No");return 0; } void spfa(int u){if(instack[u]){flag=1;return;}instack[u]=true;vector<node> s=v[u];for (int i = 0; i < s.size(); ++i) {if(dis[u]+s[i].w<dis[s[i].d]){dis[s[i].d]=dis[u]+s[i].w;spfa(s[i].d);if(flag)return;}}instack[u]=false; }

  

?

轉載于:https://www.cnblogs.com/clarencezzh/p/10382939.html

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的最短路径之spfa的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 国产在线一区二区三区四区 | 99热这里只有精品首页 | 青娱乐青青草 | 中国妇女做爰视频 | 天天操天天操天天操天天 | www.污在线观看 | 秋霞毛片 | 国产成人在线观看网站 | 欧美日韩激情视频在线观看 | 久久久久久亚洲中文字幕无码 | 欧美aaa级片 | 精品人妻少妇一区二区 | 成人免费xxxxx在线观看 | 波多野结衣啪啪 | 午夜影视剧场 | 闺蜜张开腿让我爽了一夜 | 成年人免费黄色 | 五月天婷婷激情 | 一区二区三区免费毛片 | 亚洲国产精品成人综合久久久 | 欧美一区二区三区影院 | www男人天堂 | 欧美日本韩国一区二区三区 | 456av| 欧美一级片免费看 | 亚洲欧美v | 亚洲欧美韩日 | 黑人黄色一级片 | 亚洲另类欧美日韩 | 四季av中文字幕一区 | 人人妻人人澡人人爽精品日本 | 自拍视频在线 | 国产精品av一区二区 | 天堂在线观看视频 | 国产中文视频 | 日韩在线精品强乱中文字幕 | 精品国产乱码久久 | 夜夜摸夜夜操 | 精品人妻无码一区二区色欲产成人 | 国产白嫩美女无套久久 | 第四色激情 | 性欧美8khd高清极品 | 亲嘴扒胸摸屁股免费视频日本网站 | 九九精品国产 | av资源站 | 日韩一级片免费观看 | 日本中文字幕一区二区 | 亚洲精品在线观看免费 | 九色综合网 | 国产精品免费av一区二区三区 | 黑人操少妇 | 精品人妻一区二区三区免费看 | 日本一区高清 | 极品美女啪啪 | 日本三级韩国三级三级a级按摩 | 男人添女人下部高潮视频 | 天堂中文网在线 | 国产经典久久久 | 久久久久久久久久国产 | 日韩精品一区二区三区无码专区 | 国产精品成人无码专区 | 欧美另类精品 | 男人天堂综合网 | 黄色高潮视频 | 在线观看色网 | 久久国产成人精品国产成人亚洲 | 91亚洲在线 | 波多野结衣一本 | 日韩美女视频在线观看 | 男生和女生差差的视频 | 久久久久久久综合色一本 | 性一交一乱一伧国产女士spa | 2018自拍偷拍| 国产精品污www在线观看 | 国产做爰xxxⅹ久久久精华液 | 毛片福利视频 | 国产福利一区在线 | 婷婷丁香亚洲 | 亚洲精品国产成人无码 | 光棍天堂av| 国产精品成久久久久三级 | 国产女人18水真多18精品一级做 | 日韩电影一区二区 | 高潮毛片 | 91嫩草精品 | 茄子视频懂你更多在线观看 | 欧美日韩中文字幕在线 | 精品人伦一区二区三电影 | 欧美少妇精品 | av影视网 | 亚洲欧美综合 | 日本中文字幕视频 | 春色av| 天天干天天插 | 国产精品久久久久久白浆 | 亚洲孕交| 国产美女喷水视频 | 在线成人日韩 | 91福利小视频 |