关于spfa的初步探究

/*
对于菜鸟,第一次接触这种大型算法,应该抽出一大段时间研究,研究这个算法我认为要有DIJ和Floyd的铺垫。
搜集各路资料,大概有以下几个要点。

1.SPFA(Shortest Path Faster Algorithm)是Bellman-Ford算法的一种队列实现,减少了不必要的冗余计算。
(啊,亲,什么是Bellman-Ford?大致:1对每条边进行|V|-1次Relax操作;2如果存在(u,v)∈E使得dis[u]+w<dis[v],
则存在负权回路;否则dis[v]即为s到v的最短距离,pre[v]为前驱。)

2.算法大致流程是用一个队列来进行维护。 初始时将源加入队列。 每次从队列中取出一个元素,并对所有与他相邻的点进行松弛,若某个相邻的点松弛成功,则将其入队。 直到队列为空时算法结束(很重要啊亲,对于我这样编码能力很渣的很重要,重要在什么?关键词"队列""相连")。

3.伪代码
Procedure SPFA;
 
Begin
  initialize-single-source(G,s);
  initialize-queue(Q);
  enqueue(Q,s);
  while not empty(Q) do 
    begin
      u:=dequeue(Q);
      for each v∈adj[u] do 
        begin
          tmp:=d[v];
          relax(u,v);
          if (tmp<>d[v]) and (not v in Q) then
            enqueue(Q,v);
        end;
    end;
End;
4.我代码能力渣,SPFA算法有两个优化算法 SLF 和 LLL: SLF,不会。

Autor:ray007great
*/






















/*
构图有2种,邻接矩阵版.最裸的最短路,对应hdu 2544
*/
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <cstdlib>
#include <cstdio>
#define N 150
#define inf 999999
using namespace std;
queue<int>q;
int n;
int vis[N],dis[N],map[N][N];
int spfa()
{
    int i;
    memset(vis,0,sizeof(vis));
    for(i=0;i<=n;i++)
        dis[i]=inf;
    q.push(1);
    vis[1]=1;
    dis[1]=0;
    while(!q.empty())
    {
        int cur=q.front();
        q.pop();
        for(i=1;i<=n;i++)
        {
            if(map[cur][i]!=inf)
            {
                if(dis[i]>dis[cur]+map[cur][i])
                {
                    dis[i]=dis[cur]+map[cur][i];
                    //pre[i]=cur;
                    if(!vis[i])
                    {
                        vis[i]=1;
                        q.push(i);
                    } 
                }
            }
        }
        vis[cur]=0;
    }
    return dis[n];
}
int main()
{
    int i,a,b,c,j,m;
    while(scanf("%d%d",&n,&m)!=EOF &&n&&m)
    {
        for(i=0;i<=n;i++)
        for(j=0;j<=n;j++)
        map[i][j]=inf;
        for(i=1;i<=m;i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            if(map[a][b]>c) 
                map[a][b]=map[b][a]=c;
        }    
        int max=spfa(); 
        printf("%d\n",max);
    }
  return 0;
} 






















/*
邻接矩阵版。附:邻接矩阵不用考虑重边。
*/
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <cstdlib>
#include <cstdio>
#define N 150
#define inf 999999
using namespace std;
struct node
{
    int from,to,value;
};
queue<int>q;
vector<node>g[N];
int n;
int vis[N],dis[N];
int spfa()
{
    int i;
    memset(vis,0,sizeof(vis));
    for(i=0;i<=n;i++)
        dis[i]=inf;
    q.push(1);
    vis[1]=1;
    dis[1]=0;
    while(!q.empty())
    {
        int cur=q.front();
        q.pop();
        for(i=0;i<g[cur].size();i++)
        {
            int k=g[cur][i].to;
            if(dis[k]>dis[cur]+g[cur][i].value)
            {
                dis[k]=dis[cur]+g[cur][i].value;
                if(!vis[k])
                {
                    vis[k]=1;
                    q.push(k);
                }    
            }
        }
        vis[cur]=0;
    }
    return dis[n];
}
int main()
{
    int i,a,b,c,j,m;
    while(scanf("%d%d",&n,&m)!=EOF &&n&&m)
    {    
        for(i=0;i<N;i++) g[i].clear();
        for(i=1;i<=m;i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            node e;
            e.from=a;
            e.to=b;
            e.value=c;
            g[e.from].push_back(e);
            e.from=b;
            e.to=a;
            g[e.from].push_back(e);
        } 
        int max=spfa(); 
        printf("%d\n",max);
    }
    return 0;
} 
  

 

posted on 2013-04-26 00:22  ray007great  阅读(136)  评论(0编辑  收藏  举报

导航