spfa_队列

转自:http://www.cnblogs.com/pushing-my-way/archive/2012/08/05/2624271.html

spfa:
1.当给定的图存在负权边时,Dijkstra等算法便没有了用武之地,而Bellman-Ford算法的复杂度又过高,SPFA算法便派上用场了.
2.我们约定有向加权图G不存在负权回路,即最短路径一定存在
3.思路:
用数组d记录每个结点的最短路径估计值,而且用邻接表来存储图G。我们采取的方法是动态逼近法:设立一个先进先出的队列用来保存待优化的结点,优化时每次取出队首结点u,并且用u点当前的最短路径估计值对离开u点所指向的结点v进行松弛操作,如果v点的最短路径估计值有所调整,且v点不在当前的队列中,就将v点放入队尾。这样不断从队列中取出结点来进行松弛操作,直至队列空为止。
4.实现方法:
建立一个队列,初始时队列里只有起始点,在建立一个表格记录起始点到所有点的最短路径(该表格的初始值要赋为极大值,该点到他本身的路径赋为0)。然后执行松弛操作,用队列里有的点去刷新起始点到所有点的最短路,如果刷新成功且被刷新点不在队列中则把该点加入到队列最后。重复执行直到队列为空.
代码:

  1 View Code 
  2  #include <iostream>
  3  #include <memory.h>
  4  #include <stdio.h>
  5  #include <queue>
  6  using namespace std;
  7  const int maxp=1000;
  8  const int maxe=1000;
  9  const int maxnum=1000;
 10  struct edge
 11  {
 12      int v;
 13      int w;
 14      int next;
 15  }edge[maxe];
 16  
 17  typedef struct
 18  {
 19      int d;
 20      int pre;
 21  }pp;
 22  pp point[maxp];
 23  int p,e;
 24  
 25  queue<int> q;
 26  bool use[maxp];
 27  
 28  void Init()
 29  {
 30      int i;
 31      for(i=1;i<=p;i++)
 32      {
 33          point[i].d=maxnum;
 34          point[i].pre=-1;
 35      }
 36      int u,v,w;
 37      int index=1;
 38      for(i=1;i<=e;i++)
 39      {
 40          cin>>u>>v>>w;
 41          edge[index].v=v;
 42          edge[index].w=w;
 43          edge[index].next=point[u].pre;
 44          point[u].pre=index;
 45          index++;
 46      }
 47  }
 48  
 49  void spfa(int s)
 50  {
 51      memset(use,false,sizeof(use));
 52      point[s].d=0;
 53      q.push(s);
 54      use[s]=true;
 55      int t,i;
 56      while(!q.empty())
 57      {
 58          t=q.front();
 59          use[t]=false;
 60          q.pop();
 61          for(i=point[t].pre;i!=-1;i=edge[i].next)
 62          {
 63              int v=edge[i].v;
 64              int w=edge[i].w;
 65              if(point[v].d>point[t].d+w)
 66              {
 67                  point[v].d=point[t].d+w;
 68                  if(!use[v])
 69                  {
 70                      q.push(v);
 71                      use[v]=true;
 72                  }
 73              }
 74          }
 75      }
 76  }
 77  
 78  int main()
 79  {
 80      cin>>p>>e;
 81      Init();
 82      spfa(1);
 83      int i;
 84      for(i=1;i<=p;i++)
 85          cout<<i<<" "<<point[i].d<<endl;
 86      return 0;
 87  }
 88  
 89  /*
 90  5 10
 91  1 2 10
 92  1 3 5
 93  2 3 2
 94  2 4 1
 95  3 2 3
 96  3 4 9
 97  3 5 2
 98  4 5 4
 99  5 1 7
100  5 4 6
101  */
原文地址:https://www.cnblogs.com/XBWer/p/2637469.html