我們首先來看一下什麼是前向星.
前向星是一種特殊的邊集陣列,我們把邊集陣列中的每一條邊按照起點從小到大排序,如果起點相同就按照終點從小到大排序,
並記錄下以某個點為起點的所有邊在陣列中的起始位置和儲存長度,那麼前向星就構造好了.
用len[i]來記錄所有以i為起點的邊在陣列中的儲存長度.
用head[i]記錄以i為邊集在陣列中的第乙個儲存位置.
那麼對於下圖:
我們輸入邊的順序為:
1 22 3
3 41 3
4 11 5
4 5那麼排完序後就得到:
編號: 1 2 3 4 5 6 7
起點u: 1 1 1 2 3 4 4
終點v: 2 3 5 3 4 1 5
得到:head[1] = 1 len[1] = 3
head[2] = 4 len[2] = 1
head[3] = 5 len[3] = 1
head[4] = 6 len[4] = 2
但是利用前向星會有排序操作,如果用快排時間至少為o(nlog(n))
如果用鏈式前向星,就可以避免排序.
我們建立邊結構體為:
struct edge
int next;
int to;
int w;
其中edge[i].to表示第i條邊的終點,edge[i].next表示與第i條邊同起點的下一條邊的儲存位置,edge[i].w為邊權值.
另外還有乙個陣列head,它是用來表示以i為起點的第一條邊儲存的位置,實際上你會發現這裡的第一條邊儲存的位置其實
在以i為起點的所有邊的最後輸入的那個編號.
head陣列一般初始化為-1,對於加邊的add函式是這樣的:
void
add(
int u,
int v,
int w)
初始化cnt = 0,這樣,現在我們還是按照上面的圖和輸入來模擬一下:
edge[0].to = 2; edge[0].next = -1; head[1] = 0;
edge[1].to = 3; edge[1].next = -1; head[2] = 1;
edge[2].to = 4; edge[2],next = -1; head[3] = 2;
edge[3].to = 3; edge[3].next = 0; head[1] = 3;
edge[4].to = 1; edge[4].next = -1; head[4] = 4;
edge[5].to = 5; edge[5].next = 3; head[1] = 5;
edge[6].to = 5; edge[6].next = 4; head[4] = 6;
很明顯,head[i]儲存的是以i為起點的所有邊中編號最大的那個,而把這個當作頂點i的第一條起始邊的位置.
這樣在遍歷時是倒著遍歷的,也就是說與輸入順序是相反的,不過這樣不影響結果的正確性.
比如以上圖為例,以節點1為起點的邊有3條,它們的編號分別是0,3,5 而head[1] = 5
我們在遍歷以u節點為起始位置的所有邊的時候是這樣的:
for
(int i=head[u]
;~i;i=edge[i]
.next)
那麼就是說先遍歷編號為5的邊,也就是head[1],然後就是edge[5].next,也就是編號3的邊,然後繼續edge[3].next,也
就是編號0的邊,可以看出是逆序的.
使用時:
int s;//s為起點
for(i=head[s]
; i!=-1
; i=e[i]
.ne)
邊集陣列的實現
無向帶權圖邊集陣列儲存 include include includeconst int max 100 最大邊數 using namespace std typedef structedge edge edgearray max 邊組陣列 用於存放邊 int createedge 建立無向帶權圖的...
建邊 鄰接矩陣 vector 鏈式向前星
圖論的中一般都會牽涉到建邊的問題,下面的這三種建邊的方法視情況選取 int main struct node vectorvt 300 vt i 中存的是以i為起點的邊,vt i 0 e vt i 1 e vt i 2 e 分別表示每條邊的終點 intmain 以sx為起點的邊 vt ex push...
鏈式向前星
我們首先來看一下什麼是前向星.前向星是一種特殊的邊集陣列,我們把邊集陣列中的每一條邊按照起點從小到大排序,如果起點相同就按照終點從小到大排序,並記錄下以某個點為起點的所有邊在陣列中的起始位置和儲存長度,那麼前向星就構造好了.用len i 來記錄所有以i為起點的邊在陣列中的儲存長度.用head i 記...