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 因為我們會...