圖論——Djikstra最短路

原理解釋

首先解釋一下它大概的應用場景以及原理:現在有這么一張圖,圖上各點之間都有一定的邊權或者說是距離。給定你一個起點(例如點1),讓你求這個點到圖上所有點的最短距離是多少?

在這里插入圖片描述

這個問題比較平常,但是突然這么一問如果之前沒有學過此算法肯定一臉懵。接下來簡單解釋一下算法的實現思路。

實現思路

  • 定義一個距離數組d[]表示起點到此點的最短距離,除了此時的點全部賦為inf

  • 定義一個標記數組v[]用來判斷此點是否訪問過,避免重復訪問

  • 對于這個點,每次對它的出點進行遍歷,找到距離最小的點處理

  • 如果說此時這條路徑到達一個點比之前的路徑到達它的距離短,就進行更新

    • 例如點1到點3:
    • 原本是1->3,距離為5
    • 后來路徑為1->4->3,距離為4
    • 此時就可以對d[3]進行更新
  • 最后輸出d數組就是起點到所有點的距離了

實現過程演示

在這里插入圖片描述

代碼

vector<pii> e[N];
int d[N],vis[N];
void dji(int s)
{for(int i=0; i<=n; i++) d[i]=INF;d[s]=0;for(int i=1; i<n; i++)//遍歷枚舉所有點{int u=0;for(int j=1; j<=n;j++)//每次找到此點出點的距離最近點if(!vis[j]&&d[j]<d[u]) u=j;vis[u]=1;//此點已經當過入點for(auto ed:e[u])//對它所有出點進行貪心處理{int v=ed.v,w=ed.w;if(d[v]>d[u]+w)d[v]=d[u]+w;}}
}
void solve()
{cin >> n >> m >> s;//點數、邊數、起點for(int i=0; i<m; i++){cin >> a >> b >> c;e[a].push_back({b,c});}dgi(s);for(int i=1; i<=n; i++) cout << d[i] << ' ';
}

優化處理

不難看出,這版代碼一共用了三個for循環,最多嵌套了兩層。時間復雜度極其高,達到了O(n2+m)O(n^{2}+m)O(n2+m),所以我們可以對它進行優化處理。

直接跳到時間復雜度最高的地方:找離入點距離最近的出點。如果說此時我們用優先隊列的最小堆來維護距離的話,堆頂的元素就一直是離入點最小的了,這樣我們就省去了去枚舉再遍歷著找的步驟。

實現過程演示

在這里插入圖片描述

代碼

priority_queue<pii,vector<pii>,greater<pii>> q;
void dji(int s)//當前點
{for(int i=0; i<=n; i++) d[i]=INT_MAX;d[s]=0;q.push({0,s});while(!q.empty()){auto t=q.top(); q.pop();int u=t.se;if(vi[u]) continue;vi[u]=1;for(auto ed:a[u]){int v=ed.fi,w=ed.se;if(d[u]+w<d[v])//當前路到此點距離比之前更優{d[v]=d[u]+w;q.push({d[v],v});}}}
}
void solve()
{cin >> n >> m >> s;//總點數、邊的數量、出發點編號for(int i=0; i<m; i++){int u,v,w;cin >> u >> v >> w;a[u].push_back({v,w});}dji(s);for(int i=1; i<=n; i++) cout << d[i] << ' ';
}

例題演示

下面看一道類似的例題:B-代價轉移

思路

雖然此題看著并沒有圖,但是Djikstra算法該有的東西此題都能對應上

  • 代價C1,C2,C3看作操作的距離
  • 目前的點就是入點,三種操作之后的數分別代表三個出點
  • 如果a更大的話直接相減就行

代碼

void dji()
{fill(v,v+N,0);//多實例重置數組fill(k,k+N,INF);//賦值priority_queue<pii,vector<pii>,greater<pii>> q;k[a]=0;//由于要從此點開始,所以設為0q.push({0,a});//將起點入隊maxx=b*2;//所有數中最大可能值,用于邊界判斷while(!q.empty()){auto [val,num]=q.top();//將當前點之前的值取出來(之前是出點)q.pop();if(v[num]) continue;//此值當過入點,跳過v[num]=1;//此時它是入點,標記pii cu[]={{num+1,c1},{num-1,c2},{num*2,c3}};//當前可以到的點for(auto [x,y]:cu){if(x<1||x>maxx) continue;//邊界處理if(k[num]+y<k[x])//如果此時的選擇比它之前的更優{k[x]=k[num]+y;//賦值、入隊q.push({k[x],x});}}}cout << k[b] << endl;
}
void solve()
{cin >> a >> b >> c1 >> c2 >> c3;if(a>=b)//b小的話就只能減了{cout << (a-b)*c2 << endl;return ;}dji();
}

之前沒學的時候總覺得這算法光聽名字就很高級,應該還很難。其實它就是一套比較成體系的貪心思想,將圖畫出來進行演示的話還是比較好理解的。

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

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

相關文章

kafka初步介紹

Kafka角色介紹TopicTopic主題的意思&#xff0c;消費者必須指定主題用于的消息發送&#xff0c;生產者也必須指定主題用于消息的接收。topic只是邏輯上的劃分。partitionpartition是分區的意思&#xff0c;他的主要作用是將發送到一個topic的數據做一個劃分。如果有4個partitio…

windows10的vs2019編譯openssl靜態庫備忘

1、下載安裝openssl源碼2、官網下載安裝activeperl或Strawberry Perl。官網下載慢&#xff0c;網盤找找。使用中activeperl有些異常提示、缺模塊&#xff0c;最后使用了Strawberry Perl。3、安裝nasm。powershell使用choco install nasm -y 即可。powershell使用cd命令打開當前…

學習筆記與效率提升指南:編程、記憶與面試備考

在學習與工作中&#xff0c;高效的記錄習慣、針對性的記憶方法和實用的技能儲備&#xff0c;是提升效率的關鍵。本文結合編程學習、面試備考和英語單詞積累&#xff0c;整理一套可落地的學習思路&#xff0c;尤其適合編程初學者。 一、學習核心原則&#xff1a;高效優先&#x…

順豐面試題

1. 你擅長處理哪類問題推薦回答&#xff1a; "我比較擅長處理以下幾類前端問題&#xff1a;性能優化&#xff1a;包括加載優化&#xff08;代碼分割、懶加載&#xff09;、運行時優化&#xff08;減少重排重繪&#xff09;等復雜組件開發&#xff1a;如表單聯動、可視化圖…

Warmup_steps 設置經驗

文章目錄什么是 Warmup&#xff1f;實現示例科學設置 Warmup 的黃金法則直觀例子什么是 Warmup&#xff1f; Warmup 是一種學習率調度策略&#xff0c;在訓練初期逐步增加學習率&#xff08;LR&#xff09;&#xff0c;而不是直接使用目標學習率。它解決了兩個關鍵問題&#x…

vue一個超簡單的菜單欄伸縮示例

代碼<template><div class"container"><!-- 左側區域 --><div class"left-side" :style"{ width: leftWidth px }">左側內容</div><!-- 右側區域 --><div class"right-side" :style"{ l…

Spark學習(Pyspark)

&#xff08;1&#xff09;Spark基礎入門 ①什么是Spark Spark是一款分布式內存計算的統一分析引擎。其特點就是對任意類型的數據進行自定義計算。Spark可以計算&#xff1a;結構化、半結構化、非結構化等各種類型的數據結構&#xff0c;同時也支持使用Python、Java、Scala、R以…

PDF壓縮原理詳解:如何在不失真的前提下減小文件體積?

與直接刪除內容不同&#xff0c;良好的PDF壓縮能在大幅減小體積的同時&#xff0c;較好地保留原有文字清晰度和圖像質量&#xff0c;兼顧實用性與視覺效果。軟件操作十分直觀&#xff0c;僅需設置輸入文件與輸出路徑&#xff0c;點擊【開始壓縮】按鈕即可啟動處理。畫質壓縮等級…

從應用場景看國產化FPGA潛力,紫光同創研討會武漢·北京站回顧

八月&#xff0c;紫光同創 FPGA 技術研討會先后在武漢、北京舉行。作為紫光同創官方合作伙伴&#xff0c;ALINX 攜紫光同創 FPGA 開發板及行業解決方案亮相&#xff0c;與來自通信、工業控制、醫療、圖像視頻、消費電子等領域的近 200 位行業專家齊聚一堂&#xff0c;通過主題演…

安卓APK包體優化全攻略

目錄 正常默認打包流程&#xff08;以Android平臺為例&#xff09; 查看編輯器打包日志 壓縮圖片 壓縮網格模型 壓縮貼圖 壓縮音頻文件 只打64位包 最終大小 正常默認打包流程&#xff08;以Android平臺為例&#xff09; 準備工作&#xff1a; 確保已安裝最新版Unity H…

嵌入式學習日記(28)進程、線程

回收資源空間子進程回收策略1、wait阻塞回收&#xff1a;一般情況下父進程專門負責回收2、waitpid非阻塞回收&#xff1a;搭配輪詢方式回收3、不回收&#xff1a;子進程任務一致執行4、異步回收&#xff1a;子進程結束后通知父進程進行回收exec 函數族三種調用外部程序的方式#i…

測試用例的一些事項

為什么要寫測試用例&#xff1f;寫測試用例的原因是為了避免遺漏測試&#xff0c;我們要根據給的文檔將邏輯都表達出來&#xff0c;不能因為簡單而不寫&#xff0c;日后版本更新就知道自己哪些測了哪些沒測。在沒有文檔的時候測試用例該怎么寫&#xff1f;大家可以考慮安全測試…

當Java遇見AI:飛算驅動的個人博客介紹智能生成風暴

一、飛算JavaAI&#xff1a;重新定義個人開發的"智能魔法棒" 1.1 開發者需求變革&#xff1a;從"技術門檻"到"創意優先"的時代 在數字化浪潮席卷全球的今天&#xff0c;個人品牌建設已成為技術從業者、創業者乃至學生的剛需——無論是程序員分享…

小程序排名優化:用戶行為數據背后的提升密碼

用戶在小程序中的每一次點擊、每一次停留、每一次分享&#xff0c;都在產生著有價值的數據。這些看似零散的用戶行為數據&#xff0c;其實隱藏著提升小程序排名的密碼。平臺在判定小程序排名時&#xff0c;用戶行為數據是重要的參考依據&#xff0c;因為它直接反映了小程序對用…

【DSP28335 入門教程】深度解析中斷系統:三級架構與響應機制

大家好&#xff0c;歡迎來到我們的 DSP28335 深度解析系列。在之前的實戰中&#xff0c;我們通過 while(1) 循環和延時函數實現了各種控制&#xff0c;這種方式被稱為輪詢。但輪詢就像一個焦急的門衛&#xff0c;需要不停地去檢查每個門口是否有人&#xff0c;既浪費精力又效率…

代碼隨想錄二刷之“字符串”~GO

1.344. 反轉字符串 - 力扣&#xff08;LeetCode&#xff09; func reverseString(s []byte) {left : 0right : len(s)-1for left < right{s[left],s[right] s[right],s[left]leftright--}return } 感悟&#xff1a;還是go語法熟練程度的問題&#xff0c;需要注意的是&am…

(!萬字血書!)文本預處理:NLP 版 “給數據洗澡” 指南

好吧&#xff0c;我承認我是個標題黨&#xff01;(不這樣你會點進來享受這篇 通俗易懂 的好文章嗎&#xff1f;) 正經標題&#xff1a;文本預處理全流程:從基礎到實踐 &#xff08;屏幕前的你&#xff0c;帥氣低調有內涵&#xff0c;美麗大方很優雅… 所以&#xff0c;求…

最新chrome瀏覽器elasticsearch-head無法安裝使用問題

chrome瀏覽器網址欄復制粘貼以下內容輸入回車 chrome://flags/#allow-legacy-mv2-extensions 找到Allow legacy extension manifest versions項右側選擇Enabled啟用&#xff0c;重啟瀏覽器即可。

CSS aspect-ratio 屬性

aspect-ratio 是 CSS 中用于控制元素寬高比的屬性&#xff0c;通過一行代碼即可實現響應式比例布局&#xff0c;無需復雜計算。它確保元素在不同屏幕尺寸下保持固定比例&#xff0c;提升響應式設計效率。一、基本語法與取值selector {aspect-ratio: <width> / <height…

FreeRTOS多核支持

個人博客&#xff1a;blogs.wurp.top 簡介 1. 多核支持概述 在傳統的單核系統中&#xff0c;FreeRTOS 通常運行在一個 CPU 核心上&#xff0c;負責任務調度、中斷處理和資源管理。然而&#xff0c;在多核系統中&#xff0c;多個核心可以并行執行不同的任務或線程&#xff0c…