算法筆記.spfa算法(bellman-ford算法的改進)

題目:(來源于AcWing)

給定一個?n?個點?m?條邊的有向圖,圖中可能存在重邊和自環,?邊權可能為負數

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

數據保證不存在負權回路。

輸入格式

第一行包含整數?n?和?m。

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

輸出格式

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

如果路徑不存在,則輸出?impossible

數據范圍

1≤n,m≤105,
圖中涉及邊長絕對值均不超過?10000。

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

改進思路:

我們發現,只有一個節點的最短路徑被更新之后,這個節點才可能被用來繼續更新其出邊的節點的最短路徑。

代碼實現:

?

#include<iostream>
#include<algorithm>
using namespace std;
#include<queue>
int n,m;
const int N = 100010;
int h[N],e[N],ne[N],w[N],idx;
int dist[N];
bool exi[N];//存儲隊列中是否已經有這個點了void add(int a,int b,int c)
{e[idx] = b;ne[idx] = h[a];w[idx] = c;h[a] = idx++;
}int spfa()
{queue<int> q;q.push(1);dist[1] = 0;exi[1] = true;while(q.size()){int nownode = q.front();q.pop();exi[nownode] = false;//取出該節點后更新exi數組//遍歷出邊for(int i = h[nownode];i!=-1;i=ne[i]){int tempnode = e[i];if(dist[tempnode] > dist[nownode]+w[i]){dist[tempnode] = dist[nownode]+w[i];if(!exi[tempnode]){q.push(tempnode);//只有本節點最短路被更新了,才需要更新這個節點的出邊exi[tempnode] =true;}}}}if(dist[n] ==0x3f3f3f3f) return 0x3f3f3f3f;return dist[n];
}int main()
{fill(h,h+N,-1);//必須在存儲邊操作前初始化fill(dist,dist+N,0x3f3f3f3f);idx = 0;scanf("%d%d",&n,&m);while(m--){int a,b,c;scanf("%d%d%d",&a,&b,&c);add(a,b,c);}int t = spfa();if(t == 0x3f3f3f3f)cout <<"impossible"<<endl;else cout << t<<endl;return 0;
}

細節:

  1. ?需要記錄隊列中是否已經存在該節點,如果已經存在,即便其被更新,也不用再添加它。

  2. 頭指針h[]要在添加邊之前初始化為-1.

spfa算法判斷負環:

只需要添加數組count[],記錄每個節點最短路徑,上的邊的數量,如果邊數>n,說明存在負環。

spfa算法的性能:?

  1. 時間復雜度可以為O(n+m),但最壞時退化為O(nm)。
  2. 可以處理自環、重邊、負環、允許邊權為負。

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/78425.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/78425.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/78425.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

07 Python 字符串全解析

文章目錄 一. 字符串的定義二. 字符串的基本用法1. 訪問字符串中的字符2. 字符串切片3. 字符串拼接4. 字符串重復5.字符串比較6.字符串成員運算 三. 字符串的常用方法1. len() 函數2. upper() 和 lower() 方法3. strip() 方法4. replace() 方法5. split() 方法 四. 字符串的進階…

Java集成Zxing和OpenCV實現二維碼生成與識別工具類

Java集成Zxing和OpenCV實現二維碼生成與識別工具類 本文將介紹如何使用Java集成Zxing和OpenCV庫&#xff0c;實現二維碼的生成和識別功能。識別方法支持多種輸入形式&#xff0c;包括File對象、文件路徑和Base64編碼。 一、環境準備 添加Maven依賴 <dependencies><…

【專題刷題】二分查找(二)

&#x1f4dd;前言說明&#xff1a; 本專欄主要記錄本人的基礎算法學習以及LeetCode刷題記錄&#xff0c;按專題劃分每題主要記錄&#xff1a;&#xff08;1&#xff09;本人解法 本人屎山代碼&#xff1b;&#xff08;2&#xff09;優質解法 優質代碼&#xff1b;&#xff…

Java—ThreadLocal底層實現原理

首先&#xff0c;ThreadLocal 本身并不提供存儲數據的功能&#xff0c;當我們操作 ThreadLocal 的時候&#xff0c;實際上操作線程對象的一個名為 threadLocals 成員變量。這個成員變量的類型是 ThreadLocal 的一個內部類 ThreadLocalMap&#xff0c;它是真正用來存儲數據的容器…

Elasticsearch(ES)中的腳本(Script)

文章目錄 一. 腳本是什么&#xff1f;1. lang&#xff08;腳本語言&#xff09;2. source&#xff08;腳本代碼&#xff09;3. params&#xff08;參數&#xff09;4. id&#xff08;存儲腳本的標識符&#xff09;5. stored&#xff08;是否為存儲腳本&#xff09;6. script 的…

客戶聯絡中心能力與客戶匹配方式

在數字化時代&#xff0c;客戶聯絡中心作為企業與客戶溝通的核心樞紐&#xff0c;其服務能力與客戶需求的精準匹配至關重要。隨著客戶期望的不斷提升&#xff0c;傳統的“一刀切”服務模式已難以滿足個性化需求&#xff0c;如何通過智能化的手段實現服務能力與客戶的高效匹配&a…

深入理解網絡原理:UDP協議詳解

在計算機網絡中&#xff0c;數據的傳輸是通過各種協議實現的&#xff0c;其中用戶數據報協議&#xff08;UDP&#xff0c;User Datagram Protocol&#xff09;作為一種重要的傳輸層協議&#xff0c;廣泛應用于實時通信、視頻流、在線游戲等場景。本文將深入探討UDP協議的特性、…

vscode切換Python環境

跑深度學習項目通常需要切換python環境&#xff0c;下面介紹如何在vscode切換python環境&#xff1a; 1.點擊vscode界面左上角 2.在彈出框選擇對應kernel

【MCP Node.js SDK 全棧進階指南】中級篇(4):MCP錯誤處理與日志系統

前言 隨著MCP應用的規模和復雜性增長,錯誤處理與日志系統的重要性也日益凸顯。一個健壯的錯誤處理策略和高效的日志系統不僅可以幫助開發者快速定位和解決問題,還能提高應用的可靠性和可維護性。本文作為中級篇的第四篇,將深入探討MCP TypeScript-SDK中的錯誤處理與日志系統…

【Qt】文件

&#x1f308; 個人主頁&#xff1a;Zfox_ &#x1f525; 系列專欄&#xff1a;Qt 目錄 一&#xff1a;&#x1f525; Qt 文件概述 二&#xff1a;&#x1f525; 輸入輸出設備類 三&#xff1a;&#x1f525; 文件讀寫類 四&#xff1a;&#x1f525; 文件和目錄信息類 五&…

代碼隨想錄算法訓練營第五十八天 | 1.拓撲排序精講 2.dijkstra(樸素版)精講 卡碼網117.網站構建 卡碼網47.參加科學大會

1.拓撲排序精講 題目鏈接&#xff1a;117. 軟件構建 文章講解&#xff1a;代碼隨想錄 思路&#xff1a; 把有向無環圖進行線性排序的算法都可以叫做拓撲排序。 實現拓撲排序的算法有兩種&#xff1a;卡恩算法&#xff08;BFS&#xff09;和DFS&#xff0c;以下BFS的實現思…

Qt實現語言切換的完整方案

在Qt中實現語言動態切換需要以下幾個關鍵步驟&#xff0c;我將提供一個完整的實現方案&#xff1a; 一、準備工作 在代碼中使用tr()標記所有需要翻譯的字符串 cpp button->setText(tr("Submit")); 創建翻譯文件 在.pro文件中添加&#xff1a; qmake TRANSLATION…

面試中被問到mybatis與jdbc有什么區別怎么辦

1. 核心區別 維度JDBCMyBatis抽象層級底層API&#xff0c;直接操作數據庫高層持久層框架&#xff0c;封裝JDBC細節代碼量需要手動編寫大量樣板代碼&#xff08;連接、異常處理等&#xff09;通過配置和映射減少冗余代碼SQL管理SQL嵌入Java代碼&#xff0c;維護困難SQL與Java代…

用于協同顯著目標檢測的小組協作學習 2021 GCoNet(總結)

摘要 一 介紹 問題一&#xff1a;以往的研究嘗試利用相關圖像之間的一致性&#xff0c;通過探索不同的共享線索[12, 13, 14]或語義連接[15, 16, 17]&#xff0c;來助力圖像組內的共同顯著目標檢測&#xff08;CoSOD&#xff09;&#xff0c;什么意思&#xff1f; 一方面是探…

OpenCV 圖形API(62)特征檢測-----在圖像中查找最顯著的角點函數goodFeaturesToTrack()

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 確定圖像上的強角點。 該函數在圖像或指定的圖像區域內找到最顯著的角點&#xff0c;如文獻[240]中所述。 函數使用 cornerMinEigenVal 或 cor…

MySQL引擎分類與選擇、SQL更新底層實現、分庫分表、讀寫分離、主從復制 - 面試實戰

MySQL引擎分類與選擇、SQL更新底層實現、分庫分表、讀寫分離、主從復制 - 面試實戰 故事背景&#xff1a; 今天&#xff0c;我們模擬一場互聯網大廠Java求職者的面試場景。面試官將針對MySQL的核心技術點進行提問&#xff0c;涵蓋MySQL引擎分類與選擇、SQL更新底層實現、分庫…

如何確保微型導軌的質量穩定?

微型導軌在精密機械中扮演著至關重要的角色&#xff0c;它們不僅影響設備的性能&#xff0c;還決定了產品的壽命。那么&#xff0c;如何通過一些關鍵步驟來提高微型導軌的穩定性呢&#xff1f; 1、嚴格篩選供應商&#xff1a;選擇具備高品質保證能力的供應商&#xff0c;確保原…

Golang編程拒絕類型不安全

簡介 在 Go 中&#xff0c;標準庫提供了多種容器類型&#xff0c;如 list、ring、heap、sync.Pool 和 sync.Map。然而&#xff0c;這些容器默認是類型不安全的&#xff0c;即它們可以接受任何類型的值&#xff0c;這可能導致運行時錯誤。為了提升代碼的類型安全性和可維護性&am…

什么是 JSON?學習JSON有什么用?在springboot項目里如何實現JSON的序列化和反序列化?

作為一個學習Javaweb的新手&#xff0c;理解JSON的序列化和反序列化非常重要&#xff0c;因為它在現代Web開發&#xff0c;特別是Spring Boot中無處不在。 什么是 JSON&#xff1f; 首先&#xff0c;我們簡單了解一下JSON (JavaScript Object Notation)。 JSON 是一種輕量級的…

iOS/Android 使用 C++ 跨平臺模塊時的內存與生命周期管理

在移動應用開發領域,跨平臺開發已經成為一種不可忽視的趨勢。隨著智能手機市場的持續擴張,開發者需要同時滿足iOS和Android兩大主流平臺的需求,而這往往意味著重復的工作量和高昂的維護成本。跨平臺開發的目標在于通過一套代碼庫實現多平臺的支持,從而降低開發成本、加速產…