zoukankan      html  css  js  c++  java
  • SPFA板子 (背景:Luogu P3371 单源最短路径)


    Luogu P3371 单源最短路径

    题目描述

    如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度。

    输入输出格式

     

    输入格式:

    第一行包含三个整数N、M、S,分别表示点的个数、有向边的个数、出发点的编号。

    接下来M行每行包含三个整数Fi、Gi、Wi,分别表示第i条有向边的出发点、目标点和长度。

    输出格式:

    一行,包含N个用空格分隔的整数,其中第i个整数表示从点S出发到点i的最短路径长度(若S=i则最短路径长度为0,若从点S无法到达点i,则最短路径长度为2147483647)

    输入输出样例

    输入样例#1:
    4 6 1
    1 2 2
    2 3 2
    2 4 1
    1 3 5
    3 4 3
    1 4 4
    输出样例#1:
    0 2 4 3

    分析:

    啊无负边权的有向图的单源最短路径

    代码+注释:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <queue>
     4 #include <vector>
     5 #define MAXN 10005
     6 #define MAXM 500005
     7 using namespace std;
     8 
     9 const long long MAX = 2147483647;
    10 
    11 int n, m, p_st;
    12 int x, y, d;
    13 vector<int> l[MAXN], dis[MAXN];  //采用邻接表的存储方式 
    14 int ans_dis[MAXN];        //答案储存数组 
    15 bool visited[MAXN];        //标记是否被访问过 
    16 
    17 void read(int a, int b, int d) {  //邻接表的读入 
    18     l[a].push_back(b);
    19     dis[a].push_back(d);
    20 }
    21 
    22 void spfa() {  //不就是按照BFS打一波… 
    23  
    24     queue<int> q;    //新建队列 
    25     visited[p_st] = true;  //源点设为已经访问过了 
    26     ans_dis[p_st] = 0;       //到源点的最短路径为0 
    27     q.push(p_st);           //进队开始BFS 
    28     
    29     while (!q.empty()) {   //开始BFS
    30         int now = q.front();  //now为目前所在的点 
    31         for (int i = 0; i < l[now].size(); i++) {  //在它周围可以去到的点里绕一圈 
    32             int u = l[now][i], v = dis[now][i];    //u表示目前遍历到的点 v为目前的点到u的距离 
    33             if (ans_dis[u] > ans_dis[now] + v)  //若可更新距离 
    34             {
    35                 ans_dis[u] = ans_dis[now] + v;  //更新 
    36                 if (!visited[u]) {
    37                     visited[u] = true;            //标记访问过 
    38                     q.push(u);                    //拉进队列 
    39                 }
    40             }
    41         }
    42         
    43         visited[now] = false;  // 不要忘记打这一句兄dei SFPA和BFS不同点 
    44         q.pop();               // 出队 
    45     }
    46     
    47 }
    48 
    49 int main() {
    50     
    51     scanf("%d%d%d", &n, &m, &p_st);  //N为点的个数 M为有向边的个数 P_ST为出发点的编号 
    52     for (int i = 1; i <= n; i++)
    53         ans_dis[i] = MAX / 3;        //当然是为了防止判断的时候爆炸而设定的 
    54     for (int i = 1; i <= m; i++) {
    55         scanf("%d%d%d", &x, &y, &d);
    56         read(x, y, d);
    57     }
    58     
    59     spfa();
    60     
    61     for (int i = 1; i <= n; i++)
    62         if (ans_dis[i] == MAX / 3) printf("%lld ", MAX); //到不了这个点 
    63         else printf("%d ", ans_dis[i]);    //到得了就输出 
    64     
    65     return 0;
    66 }

    (仅供个人复习使用)

  • 相关阅读:
    NOIP模拟 10
    无聊的 邮递员 插头dp
    类实例化对象可以访问静态(static)方法,但是不能访问静态属性。
    PHP——抽象类与接口的区别
    工厂模式
    win10 专业版 git bash 闪退问题终极解决方案
    git基本的使用原理
    排序算法-插入排序
    如何进行CodeReview
    php中的各种http报错的报错的状态码的分析
  • 原文地址:https://www.cnblogs.com/SJum/p/8973684.html
Copyright © 2011-2022 走看看