Dijkstra总结

本文介绍了Dijkstra算法的基本思想和步骤,强调了其解决有向图中最短路径问题的能力,特别是不能处理负权边的特点。通过逐步解析算法过程,展示了如何从起点扩展到所有可达顶点,并给出了代码模板。
摘要由CSDN通过智能技术生成

在家闲来无事,就把Dijkstra算法总结了一下,顺便加强巩固,希望对大家有帮助,理解的不够全面,希望大神们多多指点。

Dijkstra算法是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题。迪杰斯特拉算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止贪心的思想)。注意Dijkstra不能处理负权边。

基本步骤:

1,把所有的结点分成2个集合:

集合一:包含已经确定最短路径的结点;

集合二:包含尚未确定最短路径的结点。

2,初始化时,集合一只包含起点,集合二包含剩余的点。

3,用贪心的思想,按照最短路径长度递增的顺序把集合二中的结点加入集合一中,直到起点v0可到达的所有节点都在集合一中。在这个过程中不断更新最短路径。

4,直到v0可到达的所有的结点都在集合一种,这样就找到了v0到其他各点的最短路径。

   

如图:求v0到其他各点的最短路径。

 


(1)开始时,s1={v0},s2={v1,v2,v3,v4}v0到各点的最短路径是{0,10,&,30,100}; 

(2)在还未进入s1的顶点之中,最短路径为v1,因此s1={v0,v1},由于v1v2有路径,因此v0到各点的最短路径更新为{0,10,60,30,100}; 

(3)在还未进入s1的顶点之中,最短路径为v3,因此s1={v0,v1,v3},由于v3v2v4有路径,因此v0到各点的最短路径更新为{0,10,50,30,90}

(4)在还未进入s1的顶点之中,最短路径为v2,因此s1={v0,v1,v3,v2},由于v2v4有路径,因此v0到各点的最短路径更新为{0,10,50,30,60};

 

算法中最关键的有两步骤,步骤一:按照最短路径长度递增的顺序把集合二中的结点加入集合一。步骤二:更新路径。

下面是二个步骤的代码模板

(1)按照最短路径长度递增的顺序把集合二中的结点加入集合一

int map[maxn][maxn];//用来存储二结点之间的路径
int dist[maxn];//存储起点到达该结点的最短路径
bool vis[maxn];//标记结点,结点为1时表示在集合一中,结点结点为0时表示结点在集合二中
int n;

int getnext(){  
    int pos=-1, dis=INF,i;  //INF为0x3f3f3f3f,代表两结点之间没路。
    for(i=1;i<=n;++i)
    if(!vis[i] && dist[i]<dis){
        dis=dist[i];pos=i;
    }
    return pos;  
}

(2) 更新路径

void Dijkstra()
{
    int i,u,sum;
    for(i=0;i<=n;++i){
        vis[i]=0;dist[i]=INF;
    }
    u=1;dist[u]=0;//初始化起点,到自身的最短路径为0;
    while(u!=-1){
        vis[u]=true;//加入集合一中
        for(i=0;i<=n;++i){
            sum=dist[u]+map[u][i];
            if(sum<dist[i])
                dist[i]=sum;//更新最短路径
        }
        u=getnext();
    }
    return ;
}
以上只是最基本的模板,根据不同的题目情况需要更改。


PS:感谢正钢之前教给我的模板。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值