SPFA模板
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
using namespace std;
const int MAXN = 60000 + 10;
const int INF = 0x3f3f3f3f;
struct node{
int from, to, dis;
}edge[MAXN];
int head[MAXN];
int nxt[MAXN];
bool vis[MAXN];
long long dist1[MAXN], dist2[MAXN];
int n, m, tot = 1;
void add(int x){
nxt[tot] = head[x];
head[x] = tot ++;
}
void spfa1(int s){
memset(dist1, 0x3f3f3f3f, sizeof(dist1));
vis[s] = true;
dist1[s] = 0;
queue<int> q;
q.push(s);
while(!q.empty()){
int u = q.front();
q.pop();
vis[u] = false;
for(int i = head[u]; i; i = nxt[i])
{
int v = edge[i].to;
if(dist1[v] > dist1[u] + edge[i].dis)
{
dist1[v] = dist1[u] + edge[i].dis;
if(!vis[v]){
vis[v] = true;
q.push(v);
}
}
}
}
}
void spfa2(int s){
memset(dist2, 0x3f3f3f3f, sizeof(dist2));
vis[s] = true;
dist2[s] = 0;
queue<int> q;
q.push(s);
while(!q.empty())
{
int u = q.front();
q.pop();
vis[u] = false;
for(int i = head[u]; i; i = nxt[i])
{
int v = edge[i].to;
if(dist2[v] > dist2[u] + edge[i].dis)
{
dist2[v] = dist2[u] + edge[i].dis;
if(!vis[v]){
vis[v] = 1;
q.push(v);
}
}
}
}
}
void init()
{
memset(head, 0, sizeof(head));
memset(nxt, 0, sizeof(nxt));
memset(vis, false, sizeof(vis));
tot = 1;
}
int main()
{
int T;
scanf("%d", &T);
while(T --)
{
init();
scanf("%d%d", &n, &m);
for(int i = 1; i <= m; i ++)
{
scanf("%d%d%d", &edge[i].from, &edge[i].to, &edge[i].dis);
add(edge[i].from);
}
spfa1(1);
init();
for(int i = 1; i <= m; i ++)
{
add(edge[i].to);
swap(edge[i].from, edge[i].to);
}
spfa2(1);
long long ans = 0;
for(int i = 1; i <= n; i ++)
ans += dist1[i] + dist2[i];
printf("%lld\n", ans);
}
return 0;
}
SPFA算法详解与实现
本文深入探讨了SPFA(Shortest Path Faster Algorithm)算法,一种改进版的Bellman-Ford算法,用于解决带负权边的最短路径问题。通过详细的代码示例,讲解了SPFA算法的实现原理与过程,包括如何处理图结构、节点遍历以及距离更新等关键步骤。适合对图论和最短路径算法感兴趣的读者。
599

被折叠的 条评论
为什么被折叠?



