無環圖的最短路和最長路徑
阿新 • • 發佈:2018-12-01
1.DAG最短路(基於拓撲排序優化的Dijkstra演算法)
拓撲排序給予了我們查詢順序的正確性,也減少了不必要的查詢.
(1)先對路徑長度陣列初始化,源點為0,其餘為無窮大(這裡用100000代替)。
(2)對圖進行遍歷,因為有n個點,外部迴圈n次。每個點e個邊內部迴圈e次(複雜度O(N+E))。按照拓撲排序進行遍歷。
第一個點必然是源點,對從源點的每一個鄰接頂點進行更新。
第二個點必然是鄰接源點的點,在第一次的基礎上,對第二個點所鄰接的點再次更新。
舉例:
void Shortest(int *top,int n,int start,int *path) { /*top 陣列放置了topsort後的頂點順序*/ TopSort(n,top); int w[MAX_N]; // 表示從源點到圖內點 v 的最短路徑 for (int i=1;i<=n;i++) { if (i==start) w[i]=0; else w[i]=100000; } for (int i=1;i<=n;i++) { int v=top[i]; vector <int> :: iterator it;//用vector表示鄰接表 // G[v].adj 表示鄰接表 for (it=G[v].adj.begin();it!=G[v].adj.end();it++) { if (w[*it]>w[v]+W[start][*it]) { w[*it]=w[v]+W[start][*it]; path[*it]=v; } } } }
2.DAG最長路徑(分析關鍵路徑)
一般圖求最長路徑是毫無意義的,因為可能存在正值圈。但是DAG圖沒有迴路,可以讓我們求出最長路徑。
求解方法實際上是與求最短路徑是類似的,不過路徑陣列初始化為負無窮大而已。
void Longest(int *top,int n,int start,int *path) { TopSort(n,top); int w[MAX_N]; // 表示從源點到圖內點 v 的最短路徑 for (int i=1;i<=n;i++) { if (i==start) w[i]=0; else w[i]=-100000; } for (int i=1;i<=n;i++) { int v=top[i]; vector <int> :: iterator it; for (it=G[v].adj.begin();it!=G[v].adj.end();it++) { if (w[*it]<w[v]+W[start][*it]) { w[*it]=w[v]+W[start][*it]; path[*it]=v; } } } }