• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
LyonLys
愿意在角落唱沙哑的歌 再大声也都是给你 请用心听 不要说话 Contact me via E-mail: lyon.lys@gmail.com
博客园    首页    新随笔    联系   管理    订阅  订阅

用优先队列优化Dij的一个代码

  以前看过SPFA的解释,看懂了却一直没有尝试着写出来。今天见到一题100000个点1000000条边的最短路问题,看到边数相对点来说是非常少的,所以我第一反应就是用Dij来做。但是考虑到普通的Dij写这个10^6条边的代码是带不动的,于是我突然想起了好像可以用优先队列来对此优化,这种优化方法叫做SPFA(纠正一下,应该说这种方法跟SPFA类似,但SPFA是对Bellman的普通队列优化)。我没有再去看SPFA的伪代码或者模板,只是凭自己对优先队列的用法来尝试着写这个优先队列优化的Dij,自己算过,理论时间复杂度是O(ke),e是边的数目,k不超过2。

  由于是第一次写这个代码,中间出现好多错误,例如,忘记检查队列是否为空而直接用pop和top。

  最后打完后测试了几组数据,都OK了。于是我就交上去,除了内存开销比较大,时间是相当理想的:

11876kB 30ms

好了,记录一下我的1Y代码吧!

 

View Code
  1 #include "cstdio"
  2 #include "cstdlib"
  3 #include "cstring"
  4 #include "cmath"
  5 #include "cctype"
  6 #include "vector"
  7 #include "set"
  8 #include "map"
  9 #include "string"
 10 #include "algorithm"
 11 #include "stack"
 12 #include "queue"
 13 
 14 #define INF 0x7fffffff
 15 #define reset(a) memset(a, 0, sizeof(a))
 16 #define copy(a, b) memcpy(a, b, sizeof(b))
 17 #define PI acos(-1)
 18 #define FMAX (1E300)
 19 #define MAX 1000000000
 20 #define feq(a, b) (fabs((a)-(b))<1E-6)
 21 #define flq(a, b) ((a)<(b)||feq(a, b))
 22 #define MAXN 10005
 23 #define BASE 137
 24 #define PASS puts("pass")
 25 #define filein freopen("test.in", "r", stdin)
 26 #define fileout freopen("test.out", "w", stdout)
 27 
 28 using namespace std;
 29 
 30 struct Point{
 31     int p;
 32     int d;
 33     bool operator < (const Point &x) const{
 34         return d > x.d;
 35     }
 36 };
 37 struct Edge{
 38     int b;
 39     int e;
 40     int d;
 41     bool operator < (const Edge &x) const{
 42         return b < x.b;
 43     }
 44     bool operator == (const Edge &x) const{
 45         return b == x.b;
 46     }
 47 }e[1000000];
 48 priority_queue<Point, vector<Point>, less<Point> >Q;
 49 int v[100001];
 50 bool vis[100001];
 51 
 52 int main(){
 53     int n, m;
 54     //filein;
 55     //fileout;
 56     pair<Edge *, Edge *> p;
 57 
 58     while (~scanf("%d%d", &n, &m)){
 59         reset(e);
 60         reset(vis);
 61 
 62         while (Q.size())
 63             Q.pop();
 64         vis[1] = true;
 65         v[1] = 0;
 66         for (int i = 2; i <= n; i++)
 67             v[i] = MAX;
 68 
 69         for (int i = 0; i < m; i++)
 70             scanf("%d%d%d", &e[i].b, &e[i].e, &e[i].d);
 71         sort(e, e + m);
 72 
 73         int cur = 1;
 74         Edge te;
 75         Point tp;
 76 
 77         tp = {1, 0};
 78         Q.push(tp);
 79         while (Q.size() && cur != n){
 80             te.b = cur;
 81             p = equal_range(e, e + m, te);
 82             //printf("search  %d  %d\n", p.first - e, p.second - e);
 83             for (int i = p.first - e, end = p.second - e; i < end; i++){
 84                 if (v[e[i].e] > v[e[i].b] + e[i].d){
 85                     v[e[i].e] = v[e[i].b] + e[i].d;
 86                     if (!vis[e[i].e]){
 87                         tp = {e[i].e, v[e[i].e]};
 88                         Q.push(tp);
 89                         //PASS;
 90                     }
 91                 }
 92             }
 93             while (Q.size() && vis[Q.top().p]){
 94                 Q.pop();
 95             }
 96             if (Q.size()){
 97                 cur = Q.top().p;
 98                 vis[cur] = true;
 99                 Q.pop();
100             }
101         }
102         printf("%d\n", v[n]);
103     }
104 
105     return 0;
106 }

 

 

——written by Lyon

posted @ 2012-05-14 13:42  LyonLys  阅读(597)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3