无权图-最短路径

如果给图中的每条边赋一个值,或称权,那么这个图就叫做带权图

带权图在我们生活中很常见,生活中的交通路线,航班航线,都可以用带权图来表述。而生活中我们常常遇到的问题是,求从一个地点到另一个地点的最短距离,也就是求图中的最短路径问题。

要求这个问题,我们首先要判断图中有没有带负值的弧,如果是带负值,要求其最短路径比较麻烦,因为如果构成了负值圈,就可以一直循环下去,这个大小是∞的。所以本博讨论的最短路径问题,是默认了图中没有负值圈的。

例图
这里写图片描述

我们将v5设置成起点,v4设置为重点。他的权可以理解为从v5到v4消耗2,从v2到v5获取10,那么就构成了一个负值圈,一直循环下去是没有结果的。

无权图最短路径

因为无权图不带权,所以对其的最短路径的讨论就只和图中所带的边数有关系。所以可以为所有的边都赋值为1。
首先要选取一个起点,起点到起点的值当然是0了。
我们要用到的方法是广度优先搜索(breath-first search)

广度优先搜索BFS : 距开始点最近的那些顶点首先被赋值,而最远的那些顶点最后被赋值。与树的层序遍历有异曲同工之妙。

如图
这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

伪代码实现

void Unweighted(Table T)     //Assume T is initiallized
{
    int CurrDist;
    Vertex V, W;

    for(CurrDist = 0; CurrDist < NumVertex; CurrDist++)
    {
        for each vertex V
        if(!T[V].know && T[V].Dist == CurrDist)
        {
            T[V].know = True;
            for each W adjacent to V
                if(T[W].Dist == Infinity)  //判断其是否无穷大 
                {
                    T[W].Dist = CurrDist+1;
                    T[W].Pash = V;
                }
        }
    }
}

但是上述算法也存在最坏情形,当整个图像链表一样是一条链时,双层循环还是要循环那么多次。之前在讨论拓扑排序时,遇到过类似的情况。这里我们也可以用一个单独的特殊的队列来排除这种低效性。
大概思路是先将顶点压入队列,在出队列时,将还未被标记的,他的下一个邻接点也入队。之后的点重复这样的操作。

void Unweighted(Table T) 
{
    Queue Q;
    Vertex V, W;

    Q = CreateQueue(NumVertex); MakeEmpty(Q);

    /*EnQueue the start Vertex S, determined elsewhere*/
    EnQueue(S, Q);

    while(!IsEmpty(Q))
    {
        V = DeQueue(Q);   
        T[V].Know = true;   //not really needed anymore 

        for each W adjacent to V
            if(T[W].Dist == Infinity)
            {
                T[W].Dist = T[V].Dist+1;
                T[W].Pash = V;
                EnQueue(W, Q);
             } 
    }
    DisposeQueue(Q);  //free the menmory
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值