1. 程式人生 > >無環圖的最短路和最長路徑

無環圖的最短路和最長路徑

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;
			}
		}
	}
}