學習筆記 dijkstra堆優化

2021-08-25 08:41:46 字數 3623 閱讀 1796

luogu例題

我參考了這篇博文

首先介紹普通的dijkstra演算法

dijkstra用於求單源最短路,但不支援負權

dijkstra演算法的過程中把點分成兩類,定義藍點為已確定最短路的點,白點為未確定最短路的點

操作為下:

確定起點s,s為藍點,初始化dis[s]=0,其他的dis=maxlongint

在白點中找dis值最小的,它已確定最短路,標記為藍點

進行鬆弛操作,把跟當前拿出來的那個點相連的點更新dis

重複2、3操作直到所有點都確定最短路

顯然,dijkstra的時間複雜度為o(n^2)

發現2操作可以用堆優化到log級別

用小根堆維護dis值,每次取出堆中第乙個,若沒標記則進行後面的步驟

code:

var

heap:array[0..1000000] of record

num,dis:longint;

end;

edge:array[0..1000000] of record

t,next,dis:longint;

end;

head,dis:array[0..1000000] of longint;

vis:array[0..1000000] of boolean;

n,m,s,x,y,z,i,e,len,num:longint;

procedure add(x,y,z:longint);

begin

inc(num);

edge[i].t := y;

edge[i].dis := z;

edge[i].next := head[x];

head[x] := num;

end;

procedure swap(var x,y:longint);

var tmp:longint;

begin

tmp := x; x := y; y := tmp;

end;

procedure push(x,y:longint);

var i:longint;

begin

inc(len);

heap[len].num := x; heap[len].dis := y;

i := len;

while i > 1 do

begin

if heap[i].dis < heap[i >> 1].dis then

begin

swap(heap[i].num,heap[i >> 1].num);

swap(heap[i].dis,heap[i >> 1].dis);

i := i >> 1;

end else break;

end;

end;

procedure pop;

var i,x:longint;

begin

heap[1].num := heap[len].num;

heap[1].dis := heap[len].dis;

dec(len);

i := 1;

while (i << 1) <= len do

begin

if ((i << 1 or 1) > len) or (heap[i << 1].dis < heap[i << 1 or 1].dis) then

x := i << 1 else x := i << 1 or 1;

if heap[i].dis > heap[x].dis then

begin

swap(heap[i].num,heap[x].num);

swap(heap[i].dis,heap[x].dis);

i := x;

end else break;

end;

end;

begin

readln(n,m,s);

for i := 1 to m do

begin

readln(x,y,z);

add(x,y,z);

end;

for i := 1 to n do dis[i] := maxlongint;

dis[s] := 0;

len := 1;

heap[1].num := s;

heap[1].dis := 0;

while len > 0 do

begin

x := heap[1].num;

y := heap[1].dis;

pop;

if vis[x] then continue;

vis[x] := true;

i := head[x];

while i <> 0 do

begin

e := edge[i].t;

if dis[e] > y + edge[i].dis then

begin

dis[e] := y + edge[i].dis;

push(e,dis[e]);

end;

i := edge[i].next;

end;

end;

for i := 1 to n do write(dis[i],' ');

end.

pascal轉c++,完成c++版的dijkstra

code:

/*

4 6 1

1 2 2

2 3 2

2 4 1

1 3 5

3 4 3

1 4 4

*/#include

#define res register int

#define ll long long

#define maxn 2 * 200010

using

namespace std;

struct node };

struct edge edge[maxn]

;int n, m, s, head[maxn]

, dis[maxn]

, vis[maxn]

, num;

inline

intread()

inline

void

add_edge

(int x,

int y,

int z)

intmain()

//dijkstra

memset

(dis,

0x3f

,sizeof

(dis)

); dis[s]=0

; priority_queue q;

q.push

((node));

while

(!q.

empty()

));}

}}//output

for(res i =

1; i <= n;

++ i)

printf

("%d "

, dis[i]);

return0;

}

dijkstra和dijkstra堆優化模板

之前qaq一直沒有準備堆優化模板,本例以pat a1003為例,整理dijkstra和dijkstra堆優化模板 我們可以發現該篇幅找最小值部分是使用量乙個for迴圈 include include using namespace std int n,m,c1,c2 int edge 510 510...

dijkstra 堆優化 路徑

別人給的模板,所以不知道鏈結 include include include include include using namespace std define maxn 1020 define inf 0x3f typedef long long ll o nlogn typedef pair ...

模板 dijkstra 堆優化

複雜度o mlogn 輸入起點s,可以得到從起點到各點的最短路距離陣列dis i 1.初始化 清空標記陣列,初始化距離陣列設為inf,起點距離設為0,開優先佇列,搜尋起點 2.搜尋 取出隊首並pop,如果隊首節點u的當前最短路比u的原先的最短路大則跳過,否則遍歷u的鄰接點如果v沒有被訪問過且u的最短...