【正文】
for(t=0。P[i][j][j]=1。j++) { v=GetVertex(G,j)。 D) { int n=( )。如果不經(jīng)過(guò)頂點(diǎn) k,則最短路徑保持 k1path不變。i++) { coutP[i]={ 。 } } } } void main( ) { Graphchar G。jn。i++) { min=MaxInt。j++)P[i][j]=0。 u=GetVertex(G,v0)。 i = 0。 = mincost+GetWeight(sv,ev)。 sv = ev。 = sVertex。 sVertex, const T amp。v p的最短路徑,以歸納假設(shè) vp應(yīng)當(dāng)已經(jīng)出現(xiàn)于 L中。,jk } 則 D[jk+1]是 v0到 vjk+1的最短路徑的長(zhǎng) . v3 v0 v5 v2 v4 50 v1 5 30 60 100 10 10 1 2 3 4 5 L D[i] 0 10 (v0,v2) 30 (v0,v4) 100 (v0,v5) 2 D[i] 0 60 (v0,v2,v3) 4 D[i] 50 (v0,v4,v3) 0 90 (v0,v4,v5) 3 D[i] 0 60 (v0,v4,v3,v5) 5 20 迪克斯特拉 Dijkstra算法 L={v0,v2,v4,v3,v5} 時(shí)間復(fù)雜性 O(n2) 令 L={vj1 ,vj2 從根 A到 B的路徑就是邊數(shù)最少的路徑,也就是中轉(zhuǎn)次數(shù)最少的路徑。 count++。 =l。 for(j=0。 PQueueEI L。 } include include define maxint 32767 template class T struct EdgeInfo { T beginVex, endVex。 } template class T int MFSet T ::FindRoot(int i) { if(i0||i=n)return 1。 int FindRoot(T item)。 int n。 C B E A F D G H 問(wèn)題 ? 將第二個(gè)分支與第三個(gè)分支連起來(lái),只要讓結(jié)點(diǎn)D的雙親由 1改為指向 A。 T 就是最小生成樹(shù) C B E A F D 6 5 3 6 4 5 2 1 5 6 C B E A F D 6 5 3 6 4 5 2 1 5 6 C B E A F D T={ (A,C), (D,F), (B,E) } T={ (A,C), (D,F), (B,E), (C,F) } T={ (A,C), (D,F), (B,E) (C,F), (B,C) } Kruskal 克魯斯卡爾算法 把所有邊都放進(jìn)優(yōu)先隊(duì)列。 closeEdge[j].adjvex=w。 closeEdge[k].lowcost=0。 else closeEdge[i].lowcost=maxint。 T s,w, v=GetVertex(G,0)。 while(!( ) amp。amp。 template class T int operator(MiniCostEdgeInfoT a, MiniCostEdgeInfoT b) { return 。 (( ))。 for (( )。 PrintList(L)。 for (( )。 } template class T int PathConnect (GraphT amp。 } 四、無(wú)向圖的連通分量和生成樹(shù) 一個(gè)圖中互相連通的點(diǎn)的極大子集叫 連通分量 。 // initialize the queue while (!( )) { vertex = ( )。 BF A Q L AB FCH ABF CHE ABFC HED ABFCH EDI ABFCHEDI template class T SeqList T amp。 adjL = GetNeighbors(vertex)。 beginVertex) { StackT S。 visited[v]=1。 SeqListT *L=new SeqListT。 G)。L, const Tamp。 col++) edge[row1][col] = edge[row][col]。row graphsize。 } (vertex)。 return。 } (vertex)。 return 1。 } return *L。 L = new SeqListT。 vertex2) { int pos1=GetVertexPos(vertex1), pos2=GetVertexPos(vertex2)。amp。 InsertEdge(S1,S2, weight)。 i++) { f S1。 int weight。 i++) for (int j = 0。 BreadthFirstSearch(const Tamp。 SeqListTamp。 vertex1, const Tamp。 SeqListTamp。 vertex)。 adj w templateclass T struct VNode { T vertex。 // iterator used to scan the vertices friend class VertexIteratorT。 DepthFirstSearch(const Tamp。 vertex1, const Tamp。 // graph modification methods void InsertVertex(const Tamp。 int GetWeight(const Tamp。L, const Tamp。 有向圖的 生成森林: 有向圖的一個(gè)子圖,含有所有頂點(diǎn),構(gòu)成若干互不相交的有向樹(shù),叫做生成森林。 無(wú)向完全圖 共有邊 1/2(n*(n1)) 條 , 有向完全圖 共有邊 n(n1) 條。 路徑的長(zhǎng) 路徑上邊的數(shù)目, 簡(jiǎn)單路徑 頂點(diǎn)都不重復(fù)的路徑, 回路 環(huán) 首尾相接的路徑, 簡(jiǎn)單回路 除第一個(gè)和最后一個(gè)頂點(diǎn)以外都不重 復(fù)的路徑, vivj連通 有路徑 vi TD(vi)= OD(vi)+ ID(vi) OD=ID, TD=2|E|, |E| =1/2*TD TD OD ID 為整個(gè)圖的總度 ,出度 ,入度數(shù)。 圖的基本概念 路徑 vi 稀疏圖 |E|nlog n 稠密圖 |E|nlog n 帶權(quán)邊 具有邊長(zhǎng)的邊 有權(quán)圖 圖的所有邊都是帶權(quán)邊。 二、圖的存儲(chǔ)結(jié)構(gòu) 用矩陣表示圖的頂點(diǎn)之間的相鄰關(guān)系。 vertex)。 vertex1, const Tamp。 vertex)。 vertex2)。 beginVertex)。 }。 EdgeT *firstedge。 A B public: ALGraph(void)。 GetNeighbors(const Tamp。 vertex2, int weight)。 DFS( )。 beginVertex)。 j MaxGraphSize。 ifstream f。 InsertVertex(S1)。 } ( )。 ( ) != vertex) { pos++。 if (pos1 == 1 || pos2 == 1) { cerr GetWeight: a vertex is not in the graph. endl。 int pos = GetVertexPos(vertex)。 } template class T int GraphT::GetFirstNeighbor(const int v) {if (v 0||vgraphsize) { cerr “The vertex is not in the graph. endl。 } for(int i = v1+1。 graphsize++。 } edge[pos1][pos2] = weight。 graphsize。row++) for (col = pos + 1。 } template class T void GraphT::DeleteEdge(const Tamp。 vertex) { SeqListIteratorT iter(L)。 }。 *L=DFS(0,visited)。 LInsert(vertex)。 SeqListT *L, adjL。 (adjL)。 Graph T ::BreadthFirstSearch( const T amp。 if (!FindVertex(*L,vertex)) { (*L).Insert(vertex)。 從一點(diǎn)出發(fā),深度優(yōu)先或廣度優(yōu)先搜索到的子圖就是 連通分量。G, T v, T w) { SeqListT L。 !( )。 cout endl。 !( )。 } PrintList(scList)。 } template class T int minimum(MiniCostEdgeInfoT *a,int n) { for(int i=0。a[i]a[min]) min=i 。amp。 closeEdge[0].lowcost=0。 } for( i=1。 //將 w加進(jìn) U for( j=0。 } } } } void main( ) { Graphchar G。 重復(fù)以下步驟,直至 T連通: 取出最小邊,判斷這條邊的兩個(gè)端點(diǎn),如果屬于T的不同的連通分支,加入 T, 把兩分支聯(lián)成一個(gè)。 C B E A F D G H C B E A F D G H 雙親表示法 用 數(shù)組 存儲(chǔ)樹(shù)的結(jié)點(diǎn) 每個(gè)結(jié)點(diǎn)中附設(shè)一個(gè)字段 指示其父結(jié)點(diǎn)的位置 A B C D E F G H 0 1 2 3 4 5 6 7 A 1 B 1 C 1 D 1 E 1 F 1 G 1 H 1 A B C D E F G H 0 1 2 3 4 5 6 7 A 1 B 1 C 1 D 1 E 1 F 1 G 1 H 1 0 1 2 3 4 5 6 7 A 1