spfa学习

循环的提前跳出:在实际操作中,贝尔曼-福特算法经常会在未达到V-1次前就出解,V-1其实是最大值。于是可以在循环中设置判定,在某次循环不再进行松弛时,直接退出循环,进行负权环判定。
具体做法是用一个队列保存待松弛的点,然后对于每个出队的点依次遍历每个与他有边相邻的点(用邻接表效率较高),如果该点可以松弛并且队列中没有该点则将它加入队列中(只有进行松弛操作的点才会对它的邻接点有影响,也就是说其邻接点才需要松弛操作),如此迭代直到队列为空。



#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define maxn 105
#define MAXN 1005
using namespace std;

int n,m,ans,cnt,sx;
bool vis[maxn];
int dist[maxn],p[maxn];
struct Node
{
	int r,cost,next;
}edge[MAXN];
void init()
{
	memset(vis,0,sizeof(vis));
	memset(p,0,sizeof(p));
	memset(dist,0x3f,sizeof(dist));
}
void addedge(int u,int v,int w)
{
	cnt++;
	edge[cnt].r=v;
	edge[cnt].cost=w;
	edge[cnt].next=p[u];
	p[u]=cnt;
}
void SPFA()
{
	int i,j,nx;
	sx=1;
	queue<int>q;
	dist[sx]=0;
	vis[sx]=1;
	q.push(sx);
	while(!q.empty())
	{
		nx=q.front();
		vis[nx]=0;
		q.pop();
		for(i=p[nx];i;i=edge[i].next)
		{
			if(dist[edge[i].r]>dist[nx]+edge[i].cost)
			{
				dist[edge[i].r]=dist[nx]+edge[i].cost;
				if(!vis[edge[i].r])
				{
					vis[edge[i].r]=1;
					q.push(edge[i].r);
				}
			}
		}
	}
}
int main()
{
	int i,j,u,v,w;
	while(~scanf("%d%d",&n,&m))
	{
		init();
		cnt=0;
		for(i=1;i<=m;i++)
		{
			scanf("%d%d%d",&u,&v,&w);
			addedge(u,v,w);
			addedge(v,u,w);
		}
		SPFA();
		for(i=1;i<=n;i++)
			printf("i:%d dist:%d\n",i,dist[i]);
	}
	return 0;
}
7 9
1 2 3
2 4 1
3 4 4 
4 6 2
3 6 8
6 7 5
4 5 6
5 7 7
1 3 2 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值