SPFA 模板

5 篇文章 0 订阅
2 篇文章 0 订阅

简单介绍

SPFA 算法是 Bellman-Ford算法 的队列优化算法的别称,通常用于求含负权边的单源最短路径,以及判负权环。
SPFA最坏情况下复杂度和朴素 Bellman-Ford 相同,为 O(VE)。
一般时间复杂度为O(ke) k是2左右的常数。
spfa具有灵活性强的优点

bfs版

void SPFA()
{
	memset(dis,127,sizeof(dis));
	memset(exist,0,sizeof(exist));
	while(q.size()) q.pop();
	int i,j;
	int x,y,z;
	dis[1]=0; exist[1]=true;
	q.push(1);
	do {
		x=q.front(); q.pop();
		exist[x]=false;
		for(i=one[x];i;i=Next[i]) {
			y=ver[i]; z=edge[i];
			if(dis[x]+z<dis[y]) {
				dis[y]=dis[x]+z;
				if(!exist[y]) { exist[y]=true; q.push(y); }
			}
		}
	} while(!q.empty());
	return;
}

dfs版

	memset(dis,127,sizeof(dis));
	dis[1]=0;
void spfa(int u) 
{
	for(int i=one[u];i;i=Next[i]) {
		long long v=ver[i],l=edge[i];
		if(dis[u]+l<dis[v]) {
			dis[v]=dis[u]+l;
			spfa(v);
		}
	}
	return;
}
bfs版完整代码
#include<bits/stdc++.h>
using namespace std;
/*给定 M 条边, N 个点的带权无向图。求 1到 N 的最短路;
第一行:N,M(N≤100000,M≤500000);
接下来M行3个正整数:
ai,bi,ci表示ai,bi之间有一条长度为ci的路,ci≤1000。*/
const int N=100000+5;
const int M=500000*2+5;
int n,m;
int dis[N];
bool exist[N];
int one[N],adj[N],ver[M],edge[M],Next[M];
int tot=0;
queue<int> q;
void add(int a,int b,int c)
{
	tot++;
	if(one[a]==0) one[a]=tot;
	Next[adj[a]]=tot;
	adj[a]=tot;
	edge[tot]=c;
	ver[tot]=b;
	return;
}
void Init()
{
	scanf("%d%d",&n,&m);
	tot=0;
	int i,j;
	int a,b,c;
	for(i=1;i<=m;i++) {
		scanf("%d%d%d",&a,&b,&c);
		add(a,b,c);
		add(b,a,c);
	}
	return;
}
void SPFA()
{
	memset(dis,127,sizeof(dis));
	memset(exist,0,sizeof(exist));
	while(q.size()) q.pop();
	int i,j;
	int x,y,z;
	dis[1]=0; exist[1]=true;
	q.push(1);
	do {
		x=q.front(); q.pop();
		exist[x]=false;
		for(i=one[x];i;i=Next[i]) {
			y=ver[i]; z=edge[i];
			if(dis[x]+z<dis[y]) {
				dis[y]=dis[x]+z;
				if(!exist[y]) { exist[y]=true; q.push(y); }
			}
		}
	} while(!q.empty());
	return;
}
int main()
{
//	freopen("1.in","r",stdin);
	Init();
	SPFA();
	cout<<dis[n];
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值