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  */

 

你可能感兴趣的:(SPFA)