摘要:本次对加权边的图进行单源最短路径搜索.
(1)与无权搜索有什么不一样?以前的算法在加权边上行不通了,这是因为从最短路径为k的点到相邻的点的路径不一定是最短路径,因为这条连接的边可能很长.
(2)基本思路:利用Dijkstra算法-
[1]首先访问起始点的所有邻接定点,找到到起始点最短的一个,将它标记为已访问.
[2]将该节点设置为当前节点,访问它的所有节点,并更新它们到起始点的最短路径距离.(一开始除了起始点本身距离都是Infinity)
[3]在所有的未访问的节点中找到一个最短路径,然后重复[1]
[4]直到所有的节点都被访问.
(3)注意细节:
[1]我们用了一个自定义的数据结构-Table.,该结构用来存放节点的距离,是否访问等信息.
[2]如果采用扫描表的办法,这个算法花费了O(|V|^2)来找最小未知点,花费了O(|E|)来更新距离.如果表是稠密的,那么该算法很好.如果不是,那么在寻找最小距离上的开销就太多了,这个时候可以考虑采用优先队列.
struct TableEntry
{
List Header;
int distance;
int path;
bool known;
};
typedef TableEntry Table[Number];
void ReadGraph(Graph G,Table T)
{
for (int i =0;i<=Number -1;i++)
{
T[i].Header = G[i];
}
}
void InitTable(Table T,Graph G,int start,int mark)
{
ReadGraph(G,T);
for (int i = 0;i<=Number-1;i++)
{
T[i].known = false;
T[i].path = Notvertex;
T[i].distance = mark;
}
T[start].distance = Infinity - mark;
}
int FindMinunknown(Table T)
{
int min = Infinity,index;
for (int i = 0;i<=Number-1;i++)
{
if (T[i].known!=true&&T[i].distance < min)
{
min = T[i].distance;
index = i;
}
}
return index;
}
void Dijstra(Table T,int start)
{
int v,w,cw,counter = 0;
while(counter <=Number-1)
{
v = FindMinunknown(T);
T[v].known = true;
T[v].Header = T[v].Header->Next;
counter++;
while(T[v].Header!=NULL)
{
w = T[v].Header->Element;
cw = T[v].Header->weight;
if(T[w].known != true&&cw+T[v].distance <T[w].distance)
{
T[w].distance = cw+T[v].distance;
T[w].path = v;
}
T[v].Header = T[v].Header->Next;
}
}
}