zkw神樹優化dijkstra

2022-05-29 07:06:14 字數 2665 閱讀 4645

zkw神樹不多說了,不懂的移步我的部落格《zkw線段樹》。這裡優化dij用,不需要區間查詢,只使用點修改乙個,程式設計複雜度極低。

唯一不同的是的為了更快找到最小值的位置(dijkstra中點的編號),需要加乙個mark標記,記錄最小值邏輯上的位置,或者說圖裡面點的編號。

奉上乙個做好的zkwheap模板,不光在這裡能用,是個能修改元素值的堆。

template < typename t > struct zkwheapnode 

zkwheapnode(const t & _value):value(_value) {}

};template < typename t, typename comp > class zkwheap

public:

zkwheap(size_t _maxn, const t & _init_value):init_value(_init_value)

~zkwheap()

t top()

// 最大元素

t top_pos()

// 最大元素位置

void modify(size_t _position, const t & _new_value)

t pop()

};

理解了zkw線段樹,也就很容易明白為什麼用zkw線段樹優化dijkstra了。

dijkstra演算法效率是θ(n^2)。事實上,運用鄰接表+堆優化可是將時間複雜度降到o(nlge)。我們將在最後用聚合分析得出這個界。

為什麼要堆優化?因為dijkstra最大的時間複雜度消耗在尋找dis中的最小值上。而用小根堆就解決了這個問題。偽**如下:

function

dijkstra(g, s) }}

}

不難發現,普通二叉堆對這樣的問題不能完美解決,相比之下,zkw線段樹就自然的多了。直接給出一段**:

void dijkstra(int

from)

for (int k = head[kn]; k; k = graph[k].next)

}} cout << dis[t] << endl;

}

幾乎是完全按照偽**寫出。

以前寫zkw線段樹的博文已經分析過,zkw線段樹的修改複雜度為θ(lgn)。在這裡的程式中,我們需要證明內層的迴圈次數不會超過o(e),從而證明zkw優化dijkstra的效率為o(nlge)。顯然,在沒有負權值的圖中,一條邊不可能有兩次被鬆弛。聚合分析一下,內層for迴圈總共至多進行o(e)次,總效率為o(

nlge

)+θ(

n)=o

(nlg

e)。考慮到e≤

n2,有o

(lge

)=o(

lgn2

)=o(

lgn)

,則複雜度可以重寫為:o(

nlgn

)tyvj 熱浪一題,zkw優化dijkstra標程:

#include 

#include

#include

#include

#include

#include

using

namespace

std;

template

< typename t > struct zkwheapnode zkwheapnode(const t & _value):value(_value)

};template

< typename t, typename comp > class zkwheap

public:

zkwheap(const size_t & _maxn, const t & _init_value):init_value(_init_value)

~zkwheap()

t top()

t top_pos()

void modify(size_t _position, const t & _new_value)

t pop()

}; const

int maxpoint = 2505;

const

int maxedge = 70005;

struct p graph[maxedge];

int head[maxpoint];

int pointer = 0;

int dis[maxpoint];

int n, m, s, t;

int zkn;

zkwheap < int, greater < int >>tree(maxpoint, 100000000);

void init()

void push_edge(int from, int to, int dis)

void dijkstra(int from)

for (int k = head[kn]; k; k = graph[k].next)

}} cout

<< dis[t] << endl;

}int main()

dijkstra(s);

return

0;}

zkw線段樹小結

zkw zkwzk w線段樹作為迴圈式線段樹具有較小的常數.其實樹狀陣列本質上就是線段樹 下標為 1,n 1,n 1,n 預處理乙個2 k n2 k n 2k n.然後總空間為2k 12 2k 1 2 k 1 4n 2 4n 2k 1 4n 後面令k 2 kk 2 k k 2k 那麼乙個葉子x xx...

鏈結 zkw線段樹

資料結構 走近zkw線段樹 一 資料結構 走近zkw線段樹 二 線段樹的擴充套件之 zkw線段樹 include define lc x x 1 define rc x x 1 1 using namespace std const int maxn 100005 int max int a,int...

線段樹和zkw線段樹

好啦,我們就開始說說線段樹吧 線段樹是個支援區間操作和查詢的東東,平時的話還是蠻實用的 下面以最基本的區間加以及查詢區間和為例 線段樹顧名思義就是棵樹嘛,葉子節點是每個基本點,它們所對應的父親就是它們的和,具體如下圖 但是對於這樣的線段樹來說,操作所需的時間是遠達不到我們的要求的 會被t 因為我們會...