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的最短...