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 }

(仅供个人复习使用)

posted @ 2018-04-30 15:01  StupidJum  阅读(148)  评论(0编辑  收藏  举报