zoukankan      html  css  js  c++  java
  • 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  */
  • 相关阅读:
    转 :table的边框属性设置总结
    Redis Sentinel 配置文件
    nginx unit的初探
    负载均衡器之 Haproxy
    利用python itchat给女朋友定时发信息
    nginx unit 的使用
    Redis Sentinel 模拟故障迁移
    Python 获取车票信息
    Nginx unit 源码安装初体验
    初识 Proxysql
  • 原文地址:https://www.cnblogs.com/XBWer/p/2637469.html
Copyright © 2011-2022 走看看