算法学习之Dijkstra单源最短路问题

一.问题描述

给定一个图,请找出一号点到其它点的最短路径

二.输入样例

6 9
1 2 1
1 3 12
2 3 9
2 4 3
3 5 5
4 3 4
4 5 13
4 6 15
5 6 4

三.思路分析

算法思路:首先我们使用邻接矩阵来储存图结构,之后,我们构造一数组d[]来保存起始点到其他点的距离,之后找到里面的最小值,也就是找到距离起始点距离最近的点,那么可以证明,起始点到达这一点的距离无疑就是这个值不回出现更小值,然后遍历和这个点相连的所有点,更新这些点到达起始点的距离d[],之后再重复这个过程,去寻找d[]中的最小值(出去之前的哪个最小值),之后利用这个点去松弛其他点,直到所有点都被确定成为距离远点的路径为最短。

      首先让我们与之前的fw算法做一个比较,看看两个算法在设计思路上面有什么异同,首先这两种算法都是要解决前一篇fw算法学习中所提出来的三种情况的问题,

和之前的fW算法的思路分析一样,我们还是想如果最短路出现的情况分为三种,而我们要做的就是找到一种可行的顺序去检验或生成最短的路径就可以了,那么依照我我们刚刚fw算法的思路,我们要一个k一个k的去检验,而和多源最短路问题有所区别的是,单源最短路会

//
//  main.cpp
//  Dijkatra
//
//  Created by 张嘉韬 on 16/3/14.
//  Copyright © 2016年 张嘉韬. All rights reserved.
//

#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
int const maxn=99999999;
int main(int argc, const char * argv[]) {
    freopen("/Users/zhangjiatao/Desktop/input.txt","r",stdin);
    int n,m,map[50][50],tempi,tempj,tempdis,dis[50],book[50];
    memset(dis,0,sizeof(dis));
    memset(book,0,sizeof(book));
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            if(i==j) map[i][j]=0;
            else map[i][j]=maxn;
        }
    }
    for(int i=1;i<=m;i++)
    {
        cin>>tempi>>tempj>>tempdis;
        map[tempi][tempj]=tempdis;
    }
//    for(int i=1;i<=n;i++)
//    {
//        for(int j=1;j<=n;j++)
//        {
//            cout<<map[i][j]<<" ";
//        }
//        cout<<endl;
//    }
//    cout<<endl;
//    for(int i=1;i<=n;i++) cout<<book[i]<<" ";
//    cout<<endl;
    for(int i=1;i<=n;i++)
    {
        dis[i]=map[1][i];
    }
//    for(int i=1;i<=n;i++) cout<<dis[i]<<" ";
//    cout<<endl;
    book[1]=1;
    for(int k=1;k<=n-1;k++)
    {
        int s=2,min=maxn;
        for(int i=1;i<=n;i++)
        {
            if(book[i]==0&&dis[i]<min)
            {
                min=dis[i];
                s=i;
            }
        }
        //cout<<k<<"|"<<s<<endl;
        book[s]=1;
        for(int i=1;i<=n;i++)
        {
            if(book[i]==0&&map[s][i]!=maxn)
            {
                if(dis[s]+map[s][i]<dis[i])
                    dis[i]=dis[s]+map[s][i];
            }
        }
    }
    for(int i=1;i<=n;i++) cout<<dis[i]<<" ";
    cout<<endl;
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值