迪杰斯特拉算法的具體應用

fill與memset的區別介紹

例一

在這里插入圖片描述

#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=500;
const int INF=1000000000;
bool isin[maxn]={false};
int G[maxn][maxn];
int path[maxn],rescue[maxn],num[maxn];
int weight[maxn];
int citynum,roadnum,begins,e;void Dijisktra(int a){fill(path,path+maxn,INF);//記錄最短距離memset(rescue,0,sizeof(rescue));//記錄點權memset(num,0,sizeof(num));//記錄最短路徑的條數path[a]=0;rescue[a]=weight[a];num[a]=1;for(int i=0;i<citynum;i++){int pi=-1,pv=INF;for(int j=0;j<citynum;j++){//找最短距離的結點if(isin[j]==false&&path[j]<pv){pi=j;pv=path[j];}}if(pi==-1) return;isin[pi]=true;for(int k=0;k<citynum;k++){if(isin[k]==false&&G[pi][k]!=INF){if(G[pi][k]+path[pi]<path[k]){path[k]=G[pi][k]+path[pi];num[k]=num[pi];//更新最短路徑數:不相同就覆蓋rescue[k]=rescue[pi]+weight[k];}else if(G[pi][k]+path[pi]==path[k]){if(rescue[pi]+weight[k]>rescue[k])rescue[k]=rescue[pi]+weight[k];//存大值num[k]+=num[pi];//最短路徑條數之和:相同累加}}}}
}
int main(){int v1,v2;//頂點及邊權-距離fill(G[0],G[0]+maxn*maxn,INF);cin>>citynum>>roadnum>>begins>>e;for(int i=0;i<citynum;i++){cin>>weight[i];//記錄點權-救援小組數目}for(int j=0;j<roadnum;j++){cin>>v1>>v2>>G[v1][v2];//建立無向圖G[v2][v1]=G[v1][v2];}Dijisktra(begins);cout<<num[e]<<" "<<rescue[e];return 0;
}

例二

在這里插入圖片描述
在這里插入圖片描述

#include <iostream>
using namespace std;
const int maxn=100;
const int INF=1000000000;
bool isin[maxn]={false};
int G[maxn][maxn],expense[maxn][maxn];
int path[maxn],cost[maxn],pre[maxn];
int citynum,roadnum,b,e;void Dijisktra(int a){//求最短路徑fill(path,path+maxn,INF);fill(cost,cost+maxn,INF);path[a]=0;cost[a]=0;for(int i=0;i<citynum;i++) pre[i]=i;for(int i=0;i<citynum;i++){int m=-1,mv=INF;for(int j=0;j<citynum;j++){if(isin[j]==false&&path[j]<mv){m=j;mv=path[j];}}if(m==-1) return;isin[m]=true;for(int k=0;k<citynum;k++){if(isin[k]==false&&G[m][k]!=INF){if(G[m][k]+path[m]<path[k]){path[k]=G[m][k]+path[m];cost[k]=expense[m][k]+cost[m];pre[k]=m;}else if(G[m][k]+path[m]==path[k]){if(cost[k]>expense[m][k]+cost[m])cost[k]=expense[m][k]+cost[m];pre[k]=m;}}}}
}
void DFSprint(int now){//打印if(now==b){cout<<now<<" ";return;}DFSprint(pre[now]);cout<<now<<" ";
}
int main(){int v1,v2;fill(G[0],G[0]+maxn*maxn,INF);fill(expense[0],expense[0]+maxn*maxn,INF);cin>>citynum>>roadnum>>b>>e;for(int i=0;i<roadnum;i++){cin>>v1>>v2>>G[v1][v2]>>expense[v1][v2];G[v2][v1]=G[v1][v2];expense[v2][v1]=expense[v1][v2];}Dijisktra(b);DFSprint(e);cout<<path[e]<<" "<<cost[e]<<endl;return 0;
}

拓展

用迪杰斯特拉+DFS求最短路徑的方法
關鍵代碼:

const int maxn=100;
const int INF=10000000000;
bool isin[maxn]={false};
int G[maxn][maxn],num;
int path[maxn],w[maxn];
vector<int> pre[maxn];//記錄最短路徑的前驅:考慮會有多個
vector<int> minPath,temPath;//只記錄最優或當前路徑void Dijisktra(int a){fill(path,path+maxn,INF);path[a]=0;for(int i=0;i<num;i++){int m=-1,mv=INF;for(int j=0;j<num;j++){if(isin[j]==false&&path[j]<mv){m=j;mv=path[j];}}if(m==-1) return;isin[m]=true;for(int k=0;k<num;k++){if(isin[k]==false&&G[m][k]!=INF){if(G[m][k]+path[m]<path[k]){path[k]=G[m][k]+path[m];//找到更優路徑,清空,裝最短的pre[k].clear();//m結點加入k結點的前驅列表中,即為pre[k][i]==m;pre[k].push_back(m);}else if(G[m][k]+path[m]==path[k]){
//此時有多條最短路徑,即存在多個前驅結點,直接加入即可pre[k].push_back(m);}}}}
}void DFSprint(int now,int begins){int optValue=0;if(now==begins){temPath.push_back(begins);if(value>optValue){//更新最優optValue=value;minPath=temPath;}temPath.pop_back();//彈出第一個return;}temPath.push_back(now);for(int i=0;i<pre[now].size();i++){//遍歷當前結點的前驅結點DFSprint(pre[now][i]);//不斷遞歸now結點的前驅列表}temPath.pop_back();//依次彈出第二個.....
}
//計算邊權和
int edge=0;
for(int i=temPath.size()-1;i>0;i--){int now=temPath[i],next=temPath[i-1];edge+=G[now][next];//計算邊權
}
//計算點權和
int weight=0;
for(int i=temPath.size()-1;i>0;i--){int now=temPath[i];//當前結點下標weight+=w[now];
}

例二:Dijiskatra+DFS

#include <iostream>
#include <vector>
using namespace std;
const int maxn=100;
const int INF=100000000;
bool isin[maxn]={false};
int G[maxn][maxn],expense[maxn][maxn];
int path[maxn],minValue=INF;
vector<int> pre[maxn],temPath,minPath;
int citynum,roadnum,b,e;void Dijisktra(int a){fill(path,path+maxn,INF);path[a]=0;for(int i=0;i<citynum;i++){int m=-1,mv=INF;for(int j=0;j<citynum;j++){if(isin[j]==false&&path[j]<mv){m=j;mv=path[j];}}if(m==-1) return;isin[m]=true;for(int k=0;k<citynum;k++){if(isin[k]==false&&G[m][k]!=INF){if(path[m]+G[m][k]<path[k]){path[k]=path[m]+G[m][k];pre[k].clear();pre[k].push_back(m);}else if(path[m]+G[m][k]==path[k]){pre[k].push_back(m);}}}}
}
void DFSprint(int now){int tempValue=0;if(now==b){temPath.push_back(now);for(int i=temPath.size()-1;i>0;i--){int v1=temPath[i],v2=temPath[i-1];tempValue+=expense[v1][v2];}if(tempValue<minValue){minValue=tempValue;minPath=temPath;}temPath.pop_back();//出隊}temPath.push_back(now);for(int i=0;i<pre[now].size();i++){DFSprint(pre[now][i]);}temPath.pop_back();
}
int main(){int v1,v2;fill(G[0],G[0]+maxn*maxn,INF);fill(expense[0],expense[0]+maxn*maxn,INF);cin>>citynum>>roadnum>>b>>e;for(int i=0;i<roadnum;i++){cin>>v1>>v2>>G[v1][v2]>>expense[v1][v2];G[v2][v1]=G[v1][v2];expense[v2][v1]=expense[v1][v2];}Dijisktra(b);DFSprint(e);for(int i=minPath.size()-1;i>=0;i--)cout<<minPath[i]<<" ";cout<<path[e]<<" "<<minValue<<endl;return 0;
}

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

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

相關文章

【深度學習數學基礎】Hebbian圖(Hebbian Graph)

Hebbian圖&#xff08;Hebbian Graph&#xff09;是一種基于神經科學原理的網絡結構&#xff0c;它受到唐納德赫布&#xff08;Donald Hebb&#xff09;提出的赫布學習規則&#xff08;Hebb’s rule&#xff09;的啟發。赫布學習規則是神經科學中描述神經元之間突觸連接如何通過…

模板方法模式 詳解 設計模式

模板方法模式 模板方法模式是一種行為型設計模式&#xff0c;它定義了一個算法的骨架&#xff0c;將一些步驟延遲到子類中實現。這種模式允許子類在不改變算法結構的情況下重新定義算法的某些步驟。 結構 抽象類&#xff08;Abstract Class&#xff09;&#xff1a;負責給出一…

JavaWeb老杜視頻筆記總結,Servlet-JSP

關于直播 什么時間直播&#xff1f; 晚上8:00到10:00 每周直播幾天&#xff1f; 3天&#xff08;周一、周三、周五&#xff09; 本周比較特殊&#xff1a;周四周五周六三天直播&#xff0c;從下周開始就是一三五直播。 直播什么內容&#xff1f; 從JavaWEB開始。&#xff08…

《深入淺出紅黑樹:一起動手實現自平衡的二叉搜索樹》

一、分析 1. 紅黑樹的性質 紅黑樹是一種自平衡的二叉搜索樹&#xff0c;它具有以下五個性質&#xff1a; &#xff08;1&#xff09;節點是紅色或黑色。 &#xff08;2&#xff09;根節點是黑色。 &#xff08;3&#xff09;所有葉子節點&#xff08;NIL節點&#xff09;是…

探索數據宇宙:深入解析大數據分析與管理技術

?? 歡迎大家來訪Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭?&#xff5e;?? &#x1f31f;&#x1f31f; 歡迎各位親愛的讀者&#xff0c;感謝你們抽出寶貴的時間來閱讀我的文章。 我是Srlua&#xff0c;在這里我會分享我的知識和經驗。&#x…

第六課:NIO簡介

一、傳統BIO的缺點 BIO屬于同步阻塞行IO,在服務器的實現模型為&#xff0c;每一個連接都要對應一個線程。當客戶端有連接請求的時候&#xff0c;服務器端需要啟動一個新的線程與之對應處理&#xff0c;這個模型有很多缺陷。當客戶端不做出進一步IO請求的時候&#xff0c;服務器…

《Spring Security 簡易速速上手小冊》第4章 授權與角色管理(2024 最新版)

文章目錄 4.1 理解授權4.1.1 基礎知識詳解授權的核心授權策略方法級安全動態權限檢查 4.1.2 主要案例&#xff1a;基于角色的頁面訪問控制案例 Demo 4.1.3 拓展案例 1&#xff1a;自定義投票策略案例 Demo測試自定義投票策略 4.1.4 拓展案例 2&#xff1a;使用方法級安全進行細…

【flutter】加載指示器(loading indicator)阻止用戶在某個操作執行期間操作頁面

在Flutter中&#xff0c;通過顯示一個加載指示器&#xff08;loading indicator&#xff09;來阻止用戶在某個操作執行期間操作頁面。以下是一個簡單的示例代碼&#xff0c;演示了按鈕被點擊后執行某操作&#xff0c;在操作完成前顯示加載指示器&#xff0c;阻止用戶操作頁面&a…

c語言數據結構(5)——棧

歡迎來到博主的專欄——C語言數據結構 博主id&#xff1a;代碼小豪 文章目錄 棧棧的順序存儲結構棧的插入空棧的初始化棧的刪除判斷空棧讀取棧頂元素數據 實現順序棧的所有代碼棧的鏈式存儲結構鏈式棧的初始化鏈式棧的入棧操作鏈式棧的出棧操作 實現鏈式棧的所有代碼 棧 棧是…

學習網絡編程No.11【傳輸層協議之UDP】

引言&#xff1a; 北京時間&#xff1a;2023/11/20/9:17&#xff0c;昨天成功更文&#xff0c;上周實現了更文兩篇&#xff0c;所以這周再接再厲。當然做題任在繼續&#xff0c;而目前做題給我的感覺以套路和技巧偏多&#xff0c;還是那句話很多東西不經歷你就是不懂&#xff…

測試人員如何向開發人員準確清晰地描述問題?

測試人員向開發人員準確清晰地描述問題可以采取以下方法&#xff1a; 提供詳細的背景和上下文信息&#xff1a;描述問題發生的環境、前提條件和操作步驟&#xff0c;讓開發人員能夠了解問題出現的場景。明確問題的癥狀和表現&#xff1a;清楚地說明問題的具體表現&#xff0c;…

【Python】2. 基礎語法

常量和表達式 我們可以把 Python 當成一個計算器, 來進行一些算術運算. 注意: print 是一個 Python 內置的 函數, 這個稍后詳細介紹. 可以使用 - * / ( ) 等運算符進行算術運算. 先算乘除, 后算加減. 運算符和數字之間, 可以沒有空格, 也可以有多個空格. 但是一般習慣上寫一…

LDR6328芯片:智能家居時代的小家電充電革新者

在當今的智能家居時代&#xff0c;小家電的供電方式正變得越來越智能化和高效化。 利用PD&#xff08;Power Delivery&#xff09;芯片進行誘騙取電&#xff0c;為后端小家電提供穩定電壓的技術&#xff0c;正逐漸成為行業的新寵。在這一領域&#xff0c;LDR6328芯片以其出色的…

Qt下使用modbus-c庫實現PLC線圈/保持寄存器的讀寫

系列文章目錄 提示&#xff1a;這里是該系列文章的所有文章的目錄 第一章&#xff1a;Qt下使用ModbusTcp通信協議進行PLC線圈/保持寄存器的讀寫&#xff08;32位有符號數&#xff09; 第二章&#xff1a;Qt下使用modbus-c庫實現PLC線圈/保持寄存器的讀寫 文章目錄 系列文章目錄…

前端Vue3項目如何打包成Docker鏡像運行

將前端Vue3項目打包成Docker鏡像并運行包括幾個主要步驟&#xff1a;項目打包、編寫Dockerfile、構建鏡像和運行容器。下面是一個基本的流程&#xff1a; 1. 項目打包 首先&#xff0c;確保你的Vue3項目可以正常運行和打包。在項目根目錄下執行以下命令來打包你的Vue3項目&am…

nest.js使用nest-winston日志一

nest-winston文檔 nest-winston - npm 參考&#xff1a;nestjs中winston日志模塊使用 - 浮的blog - SegmentFault 思否 安裝 cnpm install --save nest-winston winstoncnpm install winston-daily-rotate-file 在main.ts中 import { NestFactory } from nestjs/core; im…

【5G 接口協議】GTP-U協議介紹

博主未授權任何人或組織機構轉載博主任何原創文章&#xff0c;感謝各位對原創的支持&#xff01; 博主鏈接 本人就職于國際知名終端廠商&#xff0c;負責modem芯片研發。 在5G早期負責終端數據業務層、核心網相關的開發工作&#xff0c;目前牽頭6G算力網絡技術標準研究。 博客…

mysql學習

查看glibc版本 ldd --version --mysql啟動失敗,嘗試啟動 1 查看錯誤日志,端口被占用,參數名寫錯,有不支持的參數 2 通過mysqld啟動 mysqld --default-filemy.cnf & 3 mysqld --no-defaults --basedir/user/local/mysql --datadir/data/mysql/3306/data/ --usermysql 4 str…

深入理解 Nginx 的負載均衡與反向代理

深入理解 Nginx 的負載均衡與反向代理 Nginx 是一個高性能的 HTTP 和反向代理服務器&#xff0c;也是一個 IMAP/POP3/SMTP 代理服務器。由于其出色的性能和靈活性&#xff0c;Nginx 已成為現代 web 架構中的重要組成部分&#xff0c;尤其是在處理高并發連接和大規模流量時。在…

找到數組的中間位置-1991-[簡單]

力扣 關鍵點 從題目中總結出公式 sum * 2 nums[i] total從左往右開始嘗試&#xff0c;尋找 i 位置滿足上面的公式&#xff0c;為什么從左開始&#xff0c;因為題目要求找到最左邊的一個用前綴和的概念來解&#xff0c;從左往右嘗試i位置的左邊所有數之和&#xff0c;右邊所有…