【Dijkstra】城市路

城市路(Dijkstra)

时间限制:1秒        内存限制:128M

题目描述

罗老师被邀请参加一个舞会,是在城市n,而罗老师当前所处的城市为1,附近还有很多城市2~n-1,有些城市之间没有直接相连的路,有些城市之间有直接相连的路,这些路都是双向的,当然也可能有多条。 现在给出直接相邻城市的路长度,罗老师想知道从城市1到城市n,最短多少距离。

输入描述

输入n, m,表示n个城市和m条路; 接下来m行,每行a b c, 表示城市a与城市b有长度为c的路。

输出描述

输出1到n的最短路。如果1到达不了n,就输出-1。

样例

输入

5 5
1 2 20
2 3 30
3 4 20
4 5 20
1 5 100

输出

90

提示

【数据规模和约定】 1≤n≤2000 1≤m≤10000 0≤c≤10000

 分析

这道题是一道经典的最短路径问题,我们可以使用Dijkstra(迪杰斯特拉)算法来做。

先来讲一下Dijkstra算法的基本思想:

 以此图为例,求V0到其余各点的最短距离:

首先建立三个数组,分别存储未确定的点(a数组)、已确定的点(b数组)、已算出的最短距离(dist):

a[]={V1,V2,V3,V4,V5};

b[]={V0};

dist[]={0};

然后查看V0可以直接到达的点,有V1、V3、V4;

从中找到距离V0最短的一个,是V4;

将V4加入到b数组中,从a数组中删除,并用dist数组记录;

然后已V4为起点寻找,找到最短的一个,并记录;

以此类推,直到找到所有点到V0的最短距离。

这就是Dijkstra算法的基本思想,了解这个之后,就可以做题了。

AC代码:

#include<iostream>
#include<cstring>
using namespace std;
const int N=10050;
const int M=2048;
int n,m;
int head[N],v[2*N],nxt[2*N],w[2*N],idx;  //由于是无向图,所以N要为2倍
int dis[M];  //存储距离
bool vis[M];  //存储点是否已被找到最短距离
void add(int x,int y,int z){  //邻接表
    v[idx]=y;
    w[idx]=z;
    nxt[idx]=head[x];
    head[x]=idx++;
}
void Dijkstra(int s){  //s是起点
    memset(dis,0x3f,sizeof(dis));
    dis[s]=0;
    for(int i=1;i<n;i++){
        int t=-1;
        for(int j=1;j<=n;j++){
            if(!vis[j]&&(t==-1||dis[t]>dis[j])){
                t=j;
            }
        }
        vis[t]=true;
        for(int j=head[t];~j;j=nxt[j]){
            int e=v[j],l=w[j];
            dis[e]=min(dis[e],dis[t]+l);
        }
    }
    if(dis[n]==0x3f3f3f3f){  //n点未被赋值,意味着不可能走到
        cout<<-1<<endl;
    }
    else{
        cout<<dis[n]<<endl;
    }
}
int main(){
    memset(head,-1,sizeof(head));
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        int a,b,c;
        cin>>a>>b>>c;
        add(a,b,c);
        add(b,a,c);  //无向图,两端都要存
    }
    Dijkstra(1);
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值