Dijkstra和多層圖 0

眾所周知,Dijkstra經常拿來解決不帶負權和環的單元最短路。我們先來看一下他的實現過程

(由于樸素版用的不多,我們直接上堆優化)

模板

#include<bits/stdc++.h> 
#define mf(x,y) make_pair(x,y)//x距離,y節點 
using namespace std; 
int read(){int s=0,fl=1;char w=getchar();while(w>'9'||w<'0'){if(w=='-')fl=-1;w=getchar();}while(w<='9'&&w>='0'){s=s*10+(w^48);w=getchar();}return fl*s;
}
const int N=1000010;
int n,m,s,tot;
int head[N],ne[N],to[N],w[N];
void add(int x,int y,int ww){to[++tot]=y;ne[tot]=head[x];head[x]=tot;w[tot]=ww;  
}  
int d[N];
bool book[N];
void dj(int s){for(int i=1;i<=n;i++){d[i]=2147483647;}d[s]=0;priority_queue<pair<int,int> >q;q.push(mf(0,s)); // 將源點及其距離為0的信息加入隊列  while(!q.empty()){  int x=q.top().second;q.pop(); // 取出距離最小的節點  if(book[x]){continue; // 如果節點已被訪問過,則跳過 }book[x]=1; // 標記節點為已訪問  for(int i=head[x];i;i=ne[i]){ // 遍歷當前節點的所有鄰接節點  int y=to[i]; // 鄰接節點的編號if(d[y]>w[i]+d[x]){ // 如果通過當前節點可以找到更短的路徑  d[y]=d[x]+w[i]; // 更新最短路徑長度  q.push(mf(-d[y],y)); // 將鄰接節點及其新的距離(取反后)加入隊列  }}}
}
int main(){  n=read(),m=read(),s=read();for(int i=1,u,v,ww;i<=m;i++){u=read(),v=read(),ww=read();add(u,v,ww);}dj(s);for(int i=1;i<=n;i++){printf("%d ",d[i]);}cout<<endl;return 0; 
}

題目1? P4568 [JLOI2011] 飛行路線 - 洛谷

據題目可知,就是把每個城市看作一個節點,每條航線為一個邊,機票費用為邊權。要求在k此免費(也就是直接去一個城市而不用給機票費用)的情況下,從s飛到t

先考慮免費這個東西怎么處理。免費我們可以看作從節點1到節點2的邊權為0。簡單來說,我們可以建立層圖

可以把這個多層圖想象成「多層停車場」,每一層對應一個「權限使用次數」,幫你理解這段代碼的作用:

  • 假設你要從起點開車到終點,停車場有?k+1?層(編號 0 到 k),每層對應 “使用了?j?次免費通行權限” 的狀態(比如 j=0 表示一次沒用到,j=1 表示用了 1 次,最多用到 j=k 次)。
  • 原始道路:每一層內部有普通道路,走一次要花?c?元(對應代碼里同層邊的權重?c)。
  • 免費通道:層與層之間有 “免費電梯”,從第?j?層到第?j+1?層可以免費換乘(對應跨層邊的權重 0),但每次換乘會消耗一次免費次數(所以最多到第 k 層)。

來看建圖的代碼:

int main(){n=read();m=read();k=read();s=read();t=read();for(int i=1;i<=m;i++){int a,b,c;a=read();b=read();c=read();for(int j=0;j<=k;j++){add(a+j*n,b+j*n,c);add(b+j*n,a+j*n,c);if(j<k){add(a+j*n,b+(j+1)*n,0);add(b+j*n,a+(j+1)*n,0);}}}

a為起點,b為終點,c為權值。內層的for循環建立了k層圖,也就是有多少免費次數就建多少層。因為第i層對應的是使用i次免費特權時圖。

if嵌套外面的語句負責建立最基礎的聯通關系,提供基礎信息

當j<k,代表免費次數沒有用完,那么就在第j*n層和下一層建立一條邊權為0的邊,也就是當前層的每一個點都有免費通行到下一層的權利。

Dijkstra部分

當我們建完多層圖后,就可以直接跑dijkstra了

void dj(int s){memset(d,0x7f,sizeof(d));d[s]=0;priority_queue<pair<int,int> >q;q.push(mf(0,s));while(!q.empty()){  int x=q.top().second;int p=q.top().first;q.pop();if (p>d[x]) continue;if(book[x]){continue;}book[x]=1;for(int i=head[x];i;i=ne[i]){  int y=to[i];if(d[y]>w[i]+d[x]){  d[y]=d[x]+w[i];q.push(mf(-d[y],y)); }}}
}

沒啥可說的

AC代碼

#include<bits/stdc++.h>
#define mf(x,y) make_pair(x,y)//x距離,y節點 using namespace std;
const int N=5000100;
int read(){int s=0,fl=1;char w=getchar();while(w>'9'||w<'0'){if(w=='-')fl=-1;w=getchar();}while(w<='9'&&w>='0'){s=s*10+(w^48);w=getchar();}return fl*s;
}
void out(int x){if(x<0)putchar('-'),x=-x;if(x<10)putchar(x+'0');else out(x/10),putchar(x%10+'0');
}
int n,m,k,s,t;
int tot;
int head[N],ne[N],to[N],w[N];
void add(int x,int y,int ww){to[++tot]=y;ne[tot]=head[x];head[x]=tot;w[tot]=ww;  
}  
int d[N];
bool book[N];
void dj(int s){memset(d,0x7f,sizeof(d));d[s]=0;priority_queue<pair<int,int> >q;q.push(mf(0,s));while(!q.empty()){  int x=q.top().second;int p=q.top().first;q.pop();if (p>d[x]) continue;if(book[x]){continue;}book[x]=1;for(int i=head[x];i;i=ne[i]){  int y=to[i];if(d[y]>w[i]+d[x]){  d[y]=d[x]+w[i];q.push(mf(-d[y],y)); }}}
}int main(){n=read();m=read();k=read();s=read();t=read();for(int i=1;i<=m;i++){int a,b,c;a=read();b=read();c=read();for(int j=0;j<=k;j++){add(a+j*n,b+j*n,c);add(b+j*n,a+j*n,c);if(j<k){add(a+j*n,b+(j+1)*n,0);add(b+j*n,a+(j+1)*n,0);}}}dj(s);int ans=1e18;for(int j=0;j<=k;j++){ans=min(ans,d[t+j*n]);}out(ans);return 0;
}

題目2

P1948 [USACO08JAN] Telephone Lines S - 洛谷

OK國際慣例,先來騙個分

不錯,下面進入正題

據題可知,我們的目的只是把1號和n連起來。和上一道題一樣,有k此免費連的機會。于是建圖其實時差不多的。

signed main(){n=read();p=read();k=read();for(int i=1;i<=p;i++){int x,y,v;x=read();y=read();v=read();for(int j=0;j<=k;j++){add(x+j*n,y+j*n,v);add(y+j*n,x+j*n,v);if(j<k){add(x+j*n,y+(j+1)*n,0);add(y+j*n,x+(j+1)*n,0);				}}}

Dijkstra部分

void dj(int s){memset(d,0x7f,sizeof(d));d[s]=0;priority_queue<pair<int,int> >q;q.push(mf(0,s));while(!q.empty()){int x=q.top().second;int p=q.top().first;q.pop();if(book[x]) continue;book[x]=1;for(int i=head[x];i;i=ne[i]){int y=to[i];int np=max(-p,w[i]);if(d[y]>np){d[y]=np;q.push(mf(-d[y],y));}}}
}

和之前一題也差不多,但是不是求最短路,而是求當前的代價和連這條電線的最大值和y節點的最小值的最小值(?)

不過做這道題一定一定要注意數組大小,當時我就是數組開小了調了半天

AC代碼

#include<bits/stdc++.h>
#define mf(a,b) make_pair(a,b)
#define int long long
using namespace std;
const int N=5000010;
int read(){int s=0,fl=1;char w=getchar();while(w>'9'||w<'0'){if(w=='-')fl=-1;w=getchar();}while(w<='9'&&w>='0'){s=s*10+(w^48);w=getchar();}return fl*s;
}
void out(int x){if(x<0)putchar('-'),x=-x;if(x<10)putchar(x+'0');else out(x/10),putchar(x%10+'0');
}
int n,p,k;
int head[N],ne[N],to[N],w[N],d[N],book[N];
int tot;
void add(int x,int y,int v){to[++tot]=y;ne[tot]=head[x];head[x]=tot;w[tot]=v;
}
void dj(int s){memset(d,0x7f,sizeof(d));d[s]=0;priority_queue<pair<int,int> >q;q.push(mf(0,s));while(!q.empty()){int x=q.top().second;int p=q.top().first;q.pop();if(book[x]) continue;book[x]=1;for(int i=head[x];i;i=ne[i]){int y=to[i];int np=max(-p,w[i]);if(d[y]>np){d[y]=np;q.push(mf(-d[y],y));}}}
}
signed main(){n=read();p=read();k=read();for(int i=1;i<=p;i++){int x,y,v;x=read();y=read();v=read();for(int j=0;j<=k;j++){add(x+j*n,y+j*n,v);add(y+j*n,x+j*n,v);if(j<k){add(x+j*n,y+(j+1)*n,0);add(y+j*n,x+(j+1)*n,0);				}}}dj(1);int ans=2e9;for(int i=0;i<=k;i++){ans=min(ans,d[n+i*n]);}out(ans==2e9?-1:ans);return 0;
}

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

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

    相關文章

    【驅動】RK3576:桌面操作系統基本概念

    1、桌面操作系統 我們常說的Ubuntu、Debian、麒麟、統信等都是總包工頭; 他們把linux內核、根文件系統(遵循 Linux 標準文件系統層次結構FHS)、包管理(軟件、庫)、桌面環境(GNOME、Xfce等)、初始化系統(Systemd)、各種服務與守護進程、安全組件等整合成一個完整的桌面…

    sfc_os!SfcQueueValidationRequest函數分析之sfc_os!IsFileInQueue

    第一部分&#xff1a;1: kd> kc# 00 sfc_os!SfcQueueValidationRequest 01 sfc_os!SfcWatchProtectedDirectoriesWorkerThread 02 kernel32!BaseThreadStart1: kd> dvRegVal 0x01129164ChangeType 5vrd 0x012bfef0Status 0n1988337684vrdexisting 0x012bffdc//// if…

    100202Title和Input組件_編輯器-react-仿低代碼平臺項目

    文章目錄1 開發兩個問卷組件1.1 Title組件1.2 Input組件1.3 畫布靜態展示TItle和Input2 Ajax獲取問卷數據&#xff0c;并存儲到Redux store2.1 API接口2.2 組件列表存儲到Redux store統一管理2.3 重構useLoadQuestionData3 在畫布顯示問卷列表&#xff0c;點擊可選中3.1 Redux獲…

    設置計劃任務自動備份mysql

    windows系統下1.創建mysql自動備份腳本mysqlback.bat需將此腳本存放在mysql的bin文件夾下。確保此腳本執行成功了在進行第2步做計劃任務。echo off REM 定義備份目錄backup_dir、備份的文件名filename set "backup_dirD:\mysqlback" set "filenamemysqlback_%da…

    飛機起落架輪軸深孔中間段電解擴孔內輪廓檢測 - 激光頻率梳 3D 輪廓檢測

    摘要&#xff1a;飛機起落架輪軸深孔中間段電解擴孔內輪廓檢測存在精度要求高、結構復雜等挑戰。本文針對電解擴孔特殊工藝特征&#xff0c;探討激光頻率梳 3D 輪廓檢測技術的應用&#xff0c;分析其檢測原理、技術優勢及在輪軸深孔檢測中的實踐&#xff0c;為電解擴孔內輪廓高…

    【軟考中級網絡工程師】知識點之入侵防御系統:筑牢網絡安全防線

    目錄一、入侵防御系統基礎概念1.1 定義與作用1.2 與其他安全設備的關系二、入侵防御系統工作原理剖析2.1 數據包捕獲與預處理2.2 深度包檢測&#xff08;DPI&#xff09;技術2.3 威脅特征匹配2.4 行為分析與機器學習輔助檢測2.5 威脅處理與響應機制三、入侵防御系統功能全面解析…

    Python爬蟲實戰:研究scrapfly-scrapers庫,構建電商/新聞/社交媒體數據采集系統

    1. 引言 1.1 研究背景與意義 在大數據與人工智能技術深度滲透各行業的背景下,數據已成為企業決策、學術研究、產品創新的核心驅動力。互聯網作為全球最大的信息載體,蘊含海量結構化與非結構化數據(如電商商品信息、新聞資訊、社交媒體動態等),其價值挖掘依賴高效的數據采…

    Python爬蟲反爬檢測失效問題的代理池輪換與請求頭偽裝實戰方案

    Python爬蟲反爬檢測失效問題的代理池輪換與請求頭偽裝實戰方案 &#x1f31f; Hello&#xff0c;我是摘星&#xff01; &#x1f308; 在彩虹般絢爛的技術棧中&#xff0c;我是那個永不停歇的色彩收集者。 &#x1f98b; 每一個優化都是我培育的花朵&#xff0c;每一個特性都是…

    【原理】C#構造函數可以標記為Static嗎

    【從UnityURP開始探索游戲渲染】專欄-直達 實例構造函數&#xff08;Instance Constructor&#xff09;不能標記為static但C#提供了一種特殊的? 靜態構造函數&#xff08;Static Constructor&#xff09;專門用于初始化靜態成員。下面依次介紹他們&#xff1a; 1. ?實例構造…

    數據結構--樹(3)

    數據結構基礎&#xff08;13&#xff09; 文章目錄數據結構基礎&#xff08;13&#xff09;--樹樹的存儲結構樹的存儲方式1&#xff1a;雙親表示法&#xff08;順序存儲&#xff09;樹的存儲方式2&#xff1a;孩子表示法樹的存儲方式3&#xff1a;孩子兄弟表示法樹轉二叉樹森林…

    sys.stdin讀取鍵盤輸入【持續更新~】

    背景sys.stdin主要用來讀取鍵盤的一行或者多行輸入&#xff0c;讀取后表達形式為字符串。下文主要探討sys.stdin.readline()的使用&#xff0c;sys.stdin.read()參考&#xff1a;sys.stdin.readline()是逐行讀取&#xff0c;通常會配合.strip()清除首尾的換行符/空格sys.stdin.…

    近閾值技術引領者:STM32U3系列的能效與安全革新

    引言 當電池供電設備已深度融入生活的每一個角落&#xff0c;功耗控制與續航能力儼然成為制約技術演進的核心瓶頸。在此背景下&#xff0c;超低功耗新系列STM32U3憑借前沿的近閾值設計理念&#xff0c;為受功耗瓶頸限制的設備提供了突破性解決方案&#xff0c;也為能耗管理開啟…

    Vue3 中的 provide 和 inject 詳解:實現跨組件通信

    一、provide 和 inject 概述在 Vue3 中&#xff0c;provide 和 inject 是一對用于實現跨層級組件通信的 API&#xff0c;它們解決了 props 需要逐層傳遞的繁瑣問題。1.1 基本概念provide (提供)&#xff1a;在祖先組件中提供數據inject (注入)&#xff1a;在任意后代組件中注入…

    Kafka 零拷貝(Zero-Copy)技術詳解

    文章目錄1. 什么是零拷貝2. Kafka 如何實現零拷貝2.1 sendfile 系統調用2.2 mmap 內存映射3. 傳統拷貝 vs 零拷貝3.1 傳統文件傳輸流程3.2 零拷貝文件傳輸流程4. Kafka 零拷貝的具體實現4.1 消息消費時的零拷貝4.2 日志段文件的零拷貝5. 零拷貝帶來的性能優勢6. 零拷貝的適用場…

    Vue 中 v-for 的使用及 Vue2 與 Vue3 的區別

    v-for 基本用法v-for 是 Vue 中用于循環渲染列表的指令&#xff0c;基本語法如下&#xff1a;運行<!-- Vue2 和 Vue3 通用基本語法 --> <div v-for"(item, index) in items" :key"item.id">{{ index }} - {{ item.name }} </div>Vue2 和…

    本地搭建dify+deepseek智能體

    今天開始搭建智能體&#xff0c;學習一下&#xff0c;也是公司轉型所需。(Windows下的docker安裝給我差點干破防了&#xff0c;安裝了一周docker才成功。我真就要放棄的時候&#xff0c;又意外成功了/(ㄒoㄒ)/~~)0、準備階段 配置Windows10的基本配置。 按下鍵盤Windows鍵&…

    網絡常識-SSE對比Websocket

    SSE&#xff08;Server-Sent Events&#xff09;和Websocket都是用于實現服務器與客戶端實時通信的技術&#xff0c;但它們的設計理念、通信模式和適用場景有顯著區別。以下從核心差異和適用場景兩方面具體說明&#xff1a; 一、核心區別維度SSE&#xff08;Server-Sent Events…

    lamp架構部署wordpress

    CentOS 7主機&#xff1a;lamp.example.comIP&#xff1a;192.168.100.101、關閉防火墻與selinux# 關閉防火墻systemctl stop firewalldsystemctl disable firewalld# 關閉selinuxvim /etc/selinux/config # 或vim /etc/sysconfig/selinuxSELINUXdisabled:wq# 重啟reboot 2、開…

    DC6v-36V轉3.2V1A恒流驅動芯片WT7017

    DC6v-36V轉3.2V1A恒流驅動芯片WT7017WT7017是一款于連續工作模式下的降壓LED恒流轉換器&#xff0c;可驅動單只或多只LED,內置高精度電流檢測器&#xff0c;能通過外置電阻設定輸出電流,開關式1A恒流芯片。軟啟動、高達1MHZ開關頻率,開路保護,輸入范圍在6V-40VDC內都能穩定可靠…

    js如何循環HTMLCollection

    場景 當使用document.getElementsByClassName方法獲取一個包含DOM節點的集合arr時&#xff0c;正常的forEach和map操作都會報一個arr.map is not a function的錯誤因為這里的arr并不是標準的 數組 (Array)&#xff0c;而是一個 HTMLCollection 解決 使用document.querySelector…