【luogu P3371 单源最短路】 模板 vector+SPFA

本文通过使用STL简化了图算法中的邻接表操作,并详细展示了如何利用STL中的容器来实现SPFA算法求解最短路径问题。尽管STL带来了代码简洁性的提升,但同时也可能带来一定的效率损失。

stl真是好,,偷懒少写邻接表,,

两个STL应用使代码简短了很多。然而还是那句话,天上不会掉馅饼,程序的效率还是有所下降的。然而,效率不是全部,人们宁可牺牲三倍效率用Java而不用C语言就是最好的例子(from_Charles E Leiserson_),具体取舍要看情况。 ——摘自luogu dalao

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <vector>
 5 #include <queue>
 6 using namespace std;
 7 const int inf = 0x7fffffff;
 8 const int maxn = 500000 + 1;
 9 struct EDGE{
10     int v, w;
11 }pos;
12 vector<EDGE> e[maxn];
13 queue<int> q;
14 int n, m, dis[maxn], s;
15 bool vis[maxn];
16 int SPFA()
17 {
18     while(!q.empty())
19     {
20         int now = q.front();
21         q.pop();
22         vis[now] = 0;
23         for(int i = 0; i < e[now].size(); i++)
24         {
25             if(dis[e[now][i].v] > dis[now] + e[now][i].w)
26             {
27                 dis[e[now][i].v] = dis[now] + e[now][i].w;
28                 if(vis[e[now][i].v] == 0)
29                 {
30                     vis[e[now][i].v] = 1;
31                     q.push(e[now][i].v);
32                 }
33             }
34         }
35     }
36 }
37 int main()
38 {
39     scanf("%d%d%d",&n,&m,&s);
40     for(int i = 1; i <= n; i++)
41     dis[i] = inf;
42     for(int i = 1; i <= m; i++)
43     {
44         int u;
45         scanf("%d%d%d",&u,&pos.v,&pos.w);
46         e[u].push_back(pos);
47     }
48     q.push(s);
49     dis[s] = 0;
50     vis[s] = 1;
51     SPFA();
52     for(int i = 1; i <= n; i++)
53     printf("%d ",dis[i]);
54     return 0;
55 }

 

转载于:https://www.cnblogs.com/MisakaAzusa/p/8995048.html

# P5905 【模板】全短路(Johnson) ## 题目描述 给定一个包含 $n$ 个结点和 $m$ 条带权边的有向图,求所有点对间的短路径长度,一条路径的长度定义为这条路径上所有边的权值和。 注意: 1. 边权**可能**为负,且图中**可能**存在重边和自环; 2. 部分数据卡 $n$ 轮 SPFA 算法。 ## 输入格式 第 $1$ 行:$2$ 个整数 $n,m$,表示给定有向图的结点数量和有向边数量。 接下来 $m$ 行:每行 $3$ 个整数 $u,v,w$,表示有一条权值为 $w$ 的有向边从编号为 $u$ 的结点连向编号为 $v$ 的结点。 ## 输出格式 若图中存在负环,输出仅一行 $-1$。 若图中不存在负环: 输出 $n$ 行:令 $dis_{i,j}$ 为从 $i$ 到 $j$ 的短路,在第 $i$ 行输出 $\sum\limits_{j=1}^n j\times dis_{i,j}$,注意这个结果可能超过 int 存储范围。 如果不存在从 $i$ 到 $j$ 的路径,则 $dis_{i,j}=10^9$;如果 $i=j$,则 $dis_{i,j}=0$。 ## 输入输出样例 #1 ### 输入 #1 ``` 5 7 1 2 4 1 4 10 2 3 7 4 5 3 4 2 -2 3 4 -3 5 3 4 ``` ### 输出 #1 ``` 128 1000000072 999999978 1000000026 1000000014 ``` ## 输入输出样例 #2 ### 输入 #2 ``` 5 5 1 2 4 3 4 9 3 4 -3 4 5 3 5 3 -2 ``` ### 输出 #2 ``` -1 ``` ## 说明/提示 【样例解释】 左图为样例 $1$ 给出的有向图,短路构成的答案矩阵为: ``` 0 4 11 8 11 1000000000 0 7 4 7 1000000000 -5 0 -3 0 1000000000 -2 5 0 3 1000000000 -1 4 1 0 ``` 右图为样例 $2$ 给出的有向图,红色标注的边构成了负环,注意给出的图不一定连通。 ![](https://cdn.luogu.com.cn/upload/image_hosting/7lb35u4u.png) 【数据范围】 对于 $100\%$ 的数据,$1\leq n\leq 3\times 10^3,\ \ 1\leq m\leq 6\times 10^3,\ \ 1\leq u,v\leq n,\ \ -3\times 10^5\leq w\leq 3\times 10^5$。 对于 $20\%$ 的数据,$1\leq n\leq 100$,不存在负环(可用于验证 Floyd 正确性) 对于另外 $20\%$ 的数据,$w\ge 0$(可用于验证 Dijkstra 正确性) upd. 添加一组 Hack 数据:针对 SPFA 的 SLF 优化
最新发布
07-18
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值