• spfa 的算法实现之一


    问题描述:
    给定一个n个顶点,m条边的有向图(其中某些边权可能为负,但保证没有负环)。请你计算从1号点到其他点的最短路(顶点从1到n编号)。

    输入格式:
    第一行两个整数n, m。
    接下来的m行,每行有三个整数u, v, l,表示u到v有一条长度为l的边。

    输出格式:
    共n-1行,第i行表示1号点到i+1号点的最短路。

    样例输入:
    3 3
    1 2 -1
    2 3 -1
    3 1 2

    样例输出:
    -1
    -2

    数据规模与约定:
    对于10%的数据,n = 2,m = 2。
    对于30%的数据,n <= 5,m <= 10。
    对于100%的数据,1 <= n <= 20000,1 <= m <= 200000,-10000 <= l <= 10000,保证从任意顶点都能到达其他所有顶点。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    #include <stdio.h>
    #include <queue>
    #include <string.h>
     
    #define Infinite 210000000
    #define ListEndFlag  -1
     
    int number_vertex;
    int number_edge;
     
    int dist[20010];
    int head[20010];
    struct{
        int to, w, next;
    }edge[200010];
     
    void SPFA()
    {
        // 用于标识顶点是否在队列中
        bool isAlreadyInQueue[20010];
     
        // 初始化数据
        for (int i = 2; i <= number_vertex; i++)
        {
            dist[i] = Infinite;
            isAlreadyInQueue[i] = false;
        }
     
        dist[1] = 0;
        isAlreadyInQueue[1] = true;
     
        std::queue<int> q;
        q.push(1);
     
        while (q.empty() == false)
        {
            const int x = q.front();
     
            for (int i = head[x]; i != ListEndFlag; i = edge[i].next)
            {
                const int y = edge[i].to;
                const int w = edge[i].w;
     
                if (dist[x] + w < dist[y])
                {
                    dist[y] = dist[x] + w;
     
                    if (isAlreadyInQueue[y] == false)
                    {
                        q.push(y);
                        isAlreadyInQueue[y] = true;
                    }
                }
            }
     
            q.pop();
            isAlreadyInQueue[x] = false;
        }
    }
     
    int main()
    {
        // 1. 读取顶点数,边数
        scanf("%d%d", &number_vertex, &number_edge);
     
        // 2. 设置 flag
        memset(head, ListEndFlag, sizeof(head));
     
        // 3. 读取边
        for (int i = 1; i <= number_edge; i++)
        {
            int x, y, w;
            scanf("%d%d%d", &x, &y, &w);
     
            edge[i].to   = y;
            edge[i].w    = w;
            edge[i].next = head[x];
     
            head[x]      = i;
        }
     
        // 4. 执行 SPFA
        SPFA();
     
        // 5. 输出结果
        for (int i = 2; i <= number_vertex; i++)
        {
            printf("%d ", dist[i]);
        }
     
        return 0;
    }
  • 相关阅读:
    各种redis的介绍:ServiceStack.Redis,StackExchange.Redis,CSRedis
    nginx 配置web服务
    安装Office Online Server
    买房哪些事?
    微服务演变:微服务架构介绍
    VUE 前端调用Base64加密,后端c#调用Base64解密
    程序员35岁前必须做完的事
    Vue 开发流程
    小程序快速认证
    vue页面打印成pdf
  • 原文地址:https://www.cnblogs.com/night-ride-depart/p/5093479.html
Copyright © 2020-2023  润新知