ACM spfa演算法(適用於存在負權)

2021-07-28 07:33:12 字數 1309 閱讀 6608

一:演算法描述

求單源最短路的spfa演算法,是一種可以處理負權邊的演算法。對於存在負權邊,迪傑斯特拉演算法不能使用,但是bellman-ford時間複雜度較高。

簡潔起見,我們約定有向加權圖g不存在負權迴路,即最短路徑一定存在。當然,我們可以在執行該演算法前做一次拓撲排序,以判斷是否存在負權迴路。

二:演算法基本步驟

幾乎所有的最短路徑演算法都是以下兩個步驟:

①初始化

②鬆弛操作

初始化:

dis陣列全部賦值為inf,vis陣列標記是否在佇列中,一開始佇列中沒有結點,所有vis陣列元素都設定為false。

佇列+鬆弛操作:

讀取隊頭元素,出隊並且修改vis陣列值為false;將與點u相連的所有點v進行鬆弛操作,如果能更新估計值(即令d[v]變小),那麼就更新,另外,如果點v沒有在佇列中,那麼要將點v入隊(記得標記),如果已經在佇列中了,那麼就不用入隊。(因為被鬆弛過的結點可能會影響到其他結點的dis值,所以要繼續入隊)

三:判斷

判斷有無負環:

如果某個點進入佇列的次數超過n次則存在負環(spfa無法處理帶負環的圖)

四:**

#include

#include

#include

#include

using

namespace

std;

const

int n = 2005;

int nodenum , edgenum;

int dis[n]; // d[i]表示源點s到i的距離

int c[n]; // 統計每乙個結點入隊的次數

bool vis[n];

const

int inf = 0x3f3f3f3f;

bool loop; //判斷是否是迴路

intmap[nodenum][nodenum];

void spfa(int start)}}

}}

五:優化策略

1.slf策略:

若要加入的結點是j,隊首結點是i,如果dis[j] < dis[i],則將j插入到隊首;否則,插入到隊尾。

2.lll策略

設隊首元素為i,佇列中所有dis的平均值是x,若dis[i] > x,則將i插入到隊尾,查詢下乙個元素知道找到乙個dis[i]<=x,則出隊進行鬆弛操作。

多執行緒適用於阻塞式IO場景,不適用於平行計算場景

python的標準實現是cpython。cpython執行python 分為2個步驟 首先,將文字原始碼解釋編譯為位元組碼,然後再用乙個直譯器去 解釋執行位元組碼。位元組碼直譯器是有狀態的,需要維護該狀態的一致性,因此使用了gil global interpreter lock,全域性直譯器鎖 gi...

適用於python的 vimrc檔案

根據我的需求做了一些小的改動。file vimrc date 2009 09 22 author gashero note 配置乙份簡單的vim配置檔案 set nocompatible 非相容模式 syntax on 開啟語法高亮 set background dark 背景色 color des...

Extjs Form用法詳解(適用於Extjs5)

extjs form用法詳解 適用於extjs5 extjs form是乙個比較常用的控制項,主要用來顯示和編輯資料的,今天這篇文章將介紹extjs form控制項的詳細用法,包括建立form 新增子項 載入和更新資料 驗證等。本文的示例 適用於extjs 4.x和extjs 5.x,在extjs ...