(复习)图论--最短路--SPFA算法

来源:互联网 发布:s曲线加速算法 博客 编辑:程序博客网 时间:2024/05/18 17:44

SPFA算法的优点绝不仅限于它优异的时间复杂度,它还可以判负权回路啊!

**定义:**SPFA(Shortest Path Faster Algorithm)(队列优化)算法是求单源最短路径的一种算法,它还有一个重要的功能是判负环(在差分约束系统中会得以体现),在Bellman-ford算法的基础上加上一个队列优化,减少了冗余的松弛操作,是一种高效的最短路算法。
——(引自百度词条)

Bellman-Ford算法:对于每一条边都不加判断地进行一次松弛操作,以得到每一个点到第一个点的最小距离,时间复杂度为O(E)。

SPFA算法:因为Bellman-Ford算法中有很多松弛操作都是多余的,所以我们只要简化它的松弛就可以了,我们发现用没有被松弛操作更新的点不能继续更新其他的点,我们就维护一个队列,用来存储松弛点的序列。

优化:邻接表+队列(最短路算法中稳定且优秀)

/*2016.8.6 BulaBulaCHN*/#include<cstdio>#include<cstdlib>#include<cmath>#include<algorithm>#include<string>#include<cstring>#include<iostream>using namespace std;struct Edge{    int from,to,next;    int val;}eage[10005];int n,m;int head[105];int tot=0;int dis[105];int que[505];bool book[10005];int top=0;int tail=0;void Insert(int x,int y,int z){    eage[++tot].from=x;    eage[tot].to=y;    eage[tot].val=z;    eage[tot].next=head[x];    head[x]=tot;}int main(){    freopen("textdata.in","r",stdin);    freopen("textdata.out","w",stdout);    scanf("%d%d",&n,&m);    for(int i=1;i<=m;i++)    {        int x,y,z;        scanf("%d%d%d",&x,&y,&z);        Insert(x,y,z);        Insert(y,x,z);    }    for(int i=1;i<=n;i++) dis[i]=999999;    dis[1]=0;    for(int i=head[1];i;i=eage[i].next)    {        if(dis[eage[i].to]>dis[1]+eage[i].val)        {            dis[eage[i].to]=dis[1]+eage[i].val;            if(!book[eage[i].to])            {                que[++tail]=eage[i].to;                book[eage[i].to]=1;            }        }    }    while(top<tail)    {        top++;        for(int i=head[que[top]];i;i=eage[i].next)        {            if(dis[eage[i].to]>dis[que[top]]+eage[i].val)            {                dis[eage[i].to]=dis[que[top]]+eage[i].val;                if(!book[eage[i].to])                {                    que[++tail]=eage[i].to;                    book[eage[i].to]=1;                }            }        }    }    for(int i=1;i<=n;i++) cout<<dis[i]<<" ";    fclose(stdin);    fclose(stdout);    return 0;}/*textdata.in4 81 2 21 3 61 4 42 3 33 1 73 4 14 1 54 3 12textdata.out0 2 5 4*/
1 0