Bootstrap

单源最短路径,迪杰斯特拉算法

> Dijkstra算法用于解决单源最短路径问题,本质其实是一种贪心

 单元最短路径
 

请编写程序求给定正权有向图的单源最短路径长度。图中包含n个顶点,编号为0至n-1,以顶点0作为源点。

输入格式:

输入第一行为两个正整数n和e,分别表示图的顶点数和边数,其中n不超过20000,e不超过1000。接下来e行表示每条边的信息,每行为3个非负整数a、b、c,其中a和b表示该边的端点编号,c表示权值。各边并非按端点编号顺序排列。

输出格式:

输出为一行整数,为按顶点编号顺序排列的源点0到各顶点的最短路径长度(不含源点到源点),每个整数后一个空格。如源点到某顶点无最短路径,则不输出该条路径长度

作者 朱允刚

单位 吉林大学

> 利用c++里的数据结构,建立邻接表(有向图)

用多个数据储存表,记录最小权重

看代码讲解前需

  • 了解pair类型及其用法
  • 熟悉队列和优先队列的访问,存储

 

#include<bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;//定义无穷大
int n, e;//节点个数,边数
typedef pair<int, int> pii;//定义pair<int ,int>类型为pii;
//(目标点,距离)
const int N = 20010;
int dist[N];//用来记录源点到其他各个点最小权重数

vector<pii> g[N];//由许多pair数组组成的容器

int main()
{
    cin >> n >> e;
    // 先都初始化为无穷大
    memset(dist, INF, sizeof dist);
    
    while (e--)
    {
        int a, b, c;
        cin >> a >> b >> c;//点,点,边的权重
        g[a].push_back({ b,c });
        //存储a顶点发出的指向b顶点的边,此边权重为c;

    }
    dist[0] = 0;//源点到自己的距离为0
    
    priority_queue<pii, vector<pii>, greater<pii>> pq;//优先队列里面的小顶堆,由小到大
    //快速排序,将权重小的放在前面
    pq.push({ 0,0 });
    //先把源点到自己的距离放进去,位于队首

    while (!pq.empty())
    {

        int w = pq.top().first;//取pair类型队首元素(用两个变量)
        //队首的权重数最小
        int md = pq.top().second;
        //因为优先队列会自动排序,所以在前面的默认是权重最小的

        pq.pop();//队首出队操作
        if (dist[md] > w) continue;//如果当前距离不是最短距离,跳过
        //注意此处一定是>0,要让md==0时可以正常进行下面的操作
        
        //g[md]里面存的是多个pii类型的数据(目标点,权重)
        for (auto t : g[md])//自动识别类型t
        //遍历当前节点所有的邻接点
        {
            int tt = t.first;
            int ww = t.second;
            //由上一点指向下一点,如果到这点的路径大于目前指向的
            //值得注意的是,前面有一步操作是将dist里面位置的路径先假设为无穷大
            if (dist[tt] > dist[md] + ww)//找最短路径
            {

                dist[tt] = dist[md] + ww;
                pq.push({ dist[tt],tt });
                //优先队列里面前面是权重,后面是目标点,便于STL排序
                // 
                //将目前由源点指向的点及其权重压入优先队列
            }
        }
    }


    for (int i = 1; i < n; i++)
    {
        if (dist[i] != INF)
            cout << dist[i] << ' ';
    }
    return 0;
}

 

;