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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

dij算法为什么不能处理负权,以及dij算法变种

發布時間:2024/4/17 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 dij算法为什么不能处理负权,以及dij算法变种 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

對于上面那張圖,是可以用dij算法求解出正確答案,但那只是巧合而已。

我們再看看下面這張圖。

?

dist[4] 是不會被正確計算的。 因為dij算法認為從隊列出來的點,(假設為u)肯定是已經求出最短路的點,標記點u。并用點u更新其它點。

所以如果存在負權使得這個點的權值更小,那么會更新dist[u], 但是因為這個點已經被標記了,所以dij算法不會用這個點來更新其它點,所以就導致了算法的錯誤。

歸結原因,dij算法在存在負權的時候,過早得確立某個點最短路,以至于如果這個點不是最短路,就會導致錯誤。

?如下面的算法所示

1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <algorithm> 5 #include <iostream> 6 #include <queue> 7 #include <stack> 8 #include <vector> 9 #include <map> 10 #include <set> 11 #include <string> 12 #include <math.h> 13 using namespace std; 14 #pragma warning(disable:4996) 15 typedef long long LL; 16 const int INF = 1<<30; 17 18 const int N = 1000 + 10; 19 struct Edge 20 { 21 int to,dist; 22 bool operator<(const Edge&rhs)const 23 { 24 return dist > rhs.dist; 25 } 26 }; 27 vector<Edge> g[N]; 28 int dist[N]; 29 bool vis[N]; 30 void dij(int start, int n) 31 { 32 memset(vis,0,sizeof(vis)); 33 for(int i=1; i<=n; ++i) 34 dist[i] = INF; 35 priority_queue<Edge> q; 36 Edge tmp,cur; 37 dist[start] = cur.dist = 0; 38 cur.to = start; 39 q.push(cur); 40 while(!q.empty()) 41 { 42 cur = q.top(); q.pop(); 43 int u = cur.to; 44 45 /* 46 如果u被用來更新過其它點,那么即使存在負權使得dist[u]變小, 47 那么dij算法也不會再用u來更新其它點,這就是dij不能處理負權回路的原因 48 */ 49 if(vis[u]) continue; 50 vis[u] = true; 51 for(int i=0; i<g[u].size(); ++i) 52 { 53 int v = g[u][i].to; 54 if(dist[v] > dist[u] + g[u][i].dist) 55 { 56 tmp.dist = dist[v] = dist[u] + g[u][i].dist; 57 tmp.to = v; 58 q.push(tmp); 59 } 60 } 61 } 62 63 } 64 65 int main() 66 { 67 int n,m,a,b,c,i; 68 Edge tmp; 69 while(scanf("%d%d",&n,&m)!=EOF) 70 { 71 for(i=0; i<m; ++i) 72 { 73 scanf("%d%d%d",&a,&b,&c); 74 tmp.to = b; 75 tmp.dist= c; 76 g[a].push_back(tmp); 77 } 78 dij(1,n); 79 for(i=1; i<=n; ++i) 80 printf("%d ",dist[i]); 81 puts(""); 82 } 83 return 0; 84 } View Code

?

4 4
1 2 3
1 3 2
2 3 -2
3 4 2
dist[0->4] = 0 3 1 4; wrong

那么我們可以對上面的算法進行改進,上面算法的問題在于,一個點如果被標記以后,那么這個點是不會用來更新其它點的,哪怕到這個點的最短路徑減小了,也不會用來更新其它點。

所以新的改進是我們允許一個點出隊列多次,只要這個點對最短路的更新有貢獻。

只要dist[u]>=cur.dist ? , ?那么我們就認為點u可能對最短路的更新有貢獻,所以讓點u去更新最短路。

1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <algorithm> 5 #include <iostream> 6 #include <queue> 7 #include <stack> 8 #include <vector> 9 #include <map> 10 #include <set> 11 #include <string> 12 #include <math.h> 13 using namespace std; 14 #pragma warning(disable:4996) 15 typedef long long LL; 16 const int INF = 1<<30; 17 /* 18 3 3 19 1 2 3 20 1 3 2 21 2 3 -2 22 23 24 4 4 25 1 2 3 26 1 3 2 27 2 3 -2 28 3 4 2 29 dist[0->4] = 0 3 1 3; correct 30 31 */ 32 const int N = 1000 + 10; 33 struct Edge 34 { 35 int to,dist; 36 bool operator<(const Edge&rhs)const 37 { 38 return dist > rhs.dist; 39 } 40 }; 41 vector<Edge> g[N]; 42 int dist[N]; 43 //允許一個點入隊列多次,是spfa算法, 可以看做是dij的變種或者bellman的變種 44 void spfa(int start, int n) 45 { 46 for(int i=1; i<=n; ++i) 47 dist[i] = INF; 48 priority_queue<Edge> q; 49 Edge tmp,cur; 50 dist[start] = cur.dist = 0; 51 cur.to = start; 52 q.push(cur); 53 while(!q.empty()) 54 { 55 cur = q.top(); q.pop(); 56 int u = cur.to; 57 if(dist[u]<cur.dist) continue; //這里就是允許點u用來多次更新其它點的關鍵 58 for(int i=0; i<g[u].size(); ++i) 59 { 60 int v = g[u][i].to; 61 if(dist[v] > dist[u] + g[u][i].dist) 62 { 63 tmp.dist = dist[v] = dist[u] + g[u][i].dist; 64 tmp.to = v; 65 q.push(tmp); 66 } 67 } 68 } 69 70 } 71 72 int main() 73 { 74 int n,m,a,b,c,i; 75 Edge tmp; 76 while(scanf("%d%d",&n,&m)!=EOF) 77 { 78 for(i=0; i<m; ++i) 79 { 80 scanf("%d%d%d",&a,&b,&c); 81 tmp.to = b; 82 tmp.dist= c; 83 g[a].push_back(tmp); 84 } 85 dij(1,n); 86 for(i=1; i<=n; ++i) 87 printf("%d ",dist[i]); 88 puts(""); 89 } 90 return 0; 91 } View Code

?

4 4
1 2 3
1 3 2
2 3 -2
3 4 2
dist[0->4] = 0 3 1 3; correct

轉載于:https://www.cnblogs.com/justPassBy/p/4511418.html

總結

以上是生活随笔為你收集整理的dij算法为什么不能处理负权,以及dij算法变种的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 日韩黄片一区二区三区 | 亚洲熟女乱综合一区二区三区 | 一区二区高清在线 | 四虎av影视| 欧美性猛交xxxx乱大交退制版 | 中文字幕乱轮 | 91调教视频| 亚洲综合激情 | 国产精品五月天 | 韩国成人在线视频 | 国产成人久久婷婷精品流白浆 | 狠狠做深爱婷婷综合一区 | 欧美精品亚洲精品日韩精品 | 天天躁夜夜操 | 成人福利视频网站 | 国产一级片在线 | 狠狠操人人干 | 意大利少妇愉情理伦片 | 毛片高清免费 | 天堂a√在线| 欧美性高潮视频 | 午夜电影网一区 | 肉丝袜脚交视频一区二区 | 男女做网站 | 亚洲理论电影在线观看 | 97视频入口| 青青av| 狠狠草视频| 女人高潮潮呻吟喷水 | 色亚洲欧美 | 日韩欧美影院 | 婷婷在线免费视频 | 一女三黑人理论片在线 | 国产精品美女久久久久图片 | 久久11| 最新欧美大片 | 超碰人人99| 天天免费视频 | 久久综合色网 | xxxxxx欧美| 国产成人在线精品 | аⅴ资源新版在线天堂 | 久久成人免费视频 | 国产h视频 | 日韩精品视频一区二区 | 欧美成人免费观看 | 欧美一级生活片 | 经典三级第一页 | 精品一二三四 | 中文字幕人妻一区 | 在线亚洲成人 | 麻豆传媒网页 | 字幕网av| 婷婷丁香六月天 | 欧美日韩亚洲在线观看 | 欧美日韩人妻精品一区在线 | av一区二区三区免费观看 | xxx精品 | 亚洲精品成人在线视频 | 国产精品普通话 | 精品无码人妻一区 | 国产aaaaaaa | 铠甲勇士猎铠 | 自拍偷拍亚洲区 | ts人妖另类精品视频系列 | 精品成人久久久 | 在线三区| 影音先锋男人站 | 国产性xxx| av片手机在线观看 | 欧美日韩精品 | 亚洲精品毛片av | 日韩在线观看中文字幕 | 日本成人在线视频网站 | 欧美日韩福利视频 | 国产欧美日本 | 久艹在线| 另类小说一区二区 | 影音先锋亚洲一区 | 国产精品99一区二区三区 | 黄色aaaa | 天堂中文字幕av | av无限看| 男人的天堂视频网站 | 国产视频你懂得 | 丰满熟妇人妻中文字幕 | 国产色啪| 精品无码人妻少妇久久久久久 | www.欧美| 久久高清精品 | 中文av免费 | 亚洲午夜无码久久久久 | 国产性70yerg老太 | 欧美日韩精品一区二区三区四区 | 日本精品一区二区三区四区 | 毛茸茸free性熟hd | 91传媒视频在线观看 | 在线看黄网址 | 久久久精品人妻一区二区三区四 |