判断有向图g中顶点i到顶点j是否有路径_掌握算法-图论-最短路径算法-Dijkstra算法...

如果图是赋权图,那么问题就变得更困难了不过我们仍然可以使用来自无权情形时的想法。

我们保留所有与前面相同的信息。因此,每个顶点或者标记为Known的,或者标记为Unknown的。像之前一样,对每一个顶点保留一个临时距离dv。这个距离实际上是使用已知顶点作为中间顶点从s到v的最短路径的长。以前一样,我们记录pv,它是引起dv变化的最后的顶点。

解决单源最短路径问题的一般方法叫做Dijkstra算法。这个有30年历史的解法是贪婪算法(greddy algorithm)最好的例子。

Dijkstra像无权最短路径一样,按阶段进行。在每个阶段,Dijkstra算法选择一个顶点v,它在所有未知顶点中具有最小的dv,同时算法声明从s到v的最短路径是已知的。阶段的其余部分由dw的值更新完成。

在无权的情况下,若dw = x则置dw = dv+1,因此,若顶点v能提供一条更短路径,则我们本质上降低了dw的值。如果我们对赋权的情形应用同样的逻辑,那么当dw的新值dv+Cv,w是一个改进的值时,我们就置dw = dv + Cv,w。

简单来说,使用通向w路径上的定点v是不是一个好主意由算法决定。

fbd5e2ac6ff0c9762bac875ded3e88c4.png

有向图G

刚开始假设节点s是v1。第一个选择的定点是v1,路径的长为0。

a8869a970728fe08915fa205d8cfcad7.png

该顶点标记为已知。既然v1已知,那么表项就需要调整。邻接到v1的顶点是v2和v4。这两个顶点的项得到调整。

dd277255d933bec9b529e218afa630b9.png

下一步选取v4并标记为已知。顶点v3,v5,v6,v7是邻接的顶点,而它们实际上都需要调整。

ef73bc8d9ba5986f059a48d26af37c22.png

接着选择v2。v4邻接的点,但已经是已知的,因此对它没有工作要做。v5是邻接的点,但不做调整,因为经过v2的值是2+10=12,而长为3的路径已经是已知的了。

6921140143da4479aa4d8a5e6244ec7d.png

下一个选取的顶点是v5,其值为3。v7是唯一的邻接顶点,但是它不用做调整,因此3+6>5。

632dd284edd1dc4813ac224984bc35e6.png

然后选取v3,对v6的距离下调为3+5=8。

0d3692f7b7e01a7a02489595bbb7ecef.png

在选取下一个顶点v7。v6下调到5+1=6。

f598925a0f5819de956de4846063a201.png

最后我们选择v6。

13cec452b7d4beb7685ea554a762009d.png

下面给出Dijkstra算法的为代码。这里我们假设,这些顶点从0到NumVertex-1标号,并通过ReadGraph我们的图可以被读入到一个邻接表中。

/*Dijkstra算法的声明*/typedef int Vertex;struct TableEntry{    List Header; /*adjacency list*/    int Known;    DistType Dist;    Vertex Path;}/*Vertices are numbered from 0*/#define NotAVertex -1typedef struct TableEntry Table[NumVertex];
/*表初始化*/void InitTable(Vertex start, Graph G, Table T){    int i;    ReadGraph(G, T);    for(i = 0; i < NumVertex; ++i){        T[i].Known = False;        T[i].Dist = Infinity;        T[i].Path = NotAVertex;    }    T[start].Dist = 0;}
/*显示实际最短路径的例程*/void PrintPath(Vertex V, Table T){    if(T[V].Path != NotAVertex){        PrintPath(T[V].PATH, T);        printf(" to");    }    printf("%v", V); /*%v is pseudocode*/}
/*Dijkstra算法的伪代码*/void Dijkstra(Table T){    Vertex V, W;    for(;;){        V = smallest unknown distance vertex;        if(V == NotAVertex)            break;        T[V].Known = True;        for each W adjancent to V            if(!T[W].known){                if(T[V].Dist + Cvw < T[W].Dist){                    /*update W*/                    Decreae(T[W].Dist to T[V].Dist + Cvw);                    T[W].Path = V;                }            }    }}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值