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

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

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

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

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

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

/*
2016.8.6 BulaBulaCHN
*/
#include
#include
#include
#include
#include<string>
#include
#include
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(topfor(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<" ";

    fclose(stdin);
    fclose(stdout);
    return 0;
}
/*
textdata.in
4 8
1 2 2
1 3 6
1 4 4
2 3 3
3 1 7
3 4 1
4 1 5
4 3 12

textdata.out
0 2 5 4
*/

你可能感兴趣的:(最短路)