Dijkstra(邻接表+优先级队列)模板

#include <iostream>
#include <algorithm>
#include <queue>
#include <climits>             //引入<climits>的类,注意如果引入<limits>会出现编译错误
#include <cstdio>
//#include <conio.h>
using namespace std;
typedef unsigned long long u64_T;    //类型定义                                                 
const int MAXN = 50001;              //定义结点个数
const u64_T INF=(u64_T)(1)<<63;  //这种方法比较常用
//const u64_T INF = ULLONG_MAX;    //定义unsigned long long 的最大值
struct edge_T {
     int v;
     u64_T w;
     edge_T *next;
}*adj[MAXN], edges[2*MAXN];     //adj[i]存储以i为起点的邻接表的指针,memo[]存储所有的边
struct node_T {              //用于优先级队列中记录节点的标号和最短路径
     int v;
     u64_T len;
     bool operator < (const node_T &nod) const { //重载优先级队列的操作符,使其从小到大排列(注意格式必须完全一致)
          return len > nod.len;
     }
};
int edgenum;              //记录边的总数
u64_T weight[MAXN];
int vn,en;             //记录定点数和边数

u64_T dist[MAXN];                     //存储结点的最小距离 
void addEdge(int u, int v, u64_T w) {   
     edge_T *ptr = &edges[edgenum ++];
     ptr -> v = v;
     ptr -> w = w;
     ptr -> next = adj[u];    //往前插入边
     adj[u] = ptr;
}
void dijkstra(int s) {             //n代表结点总数
     priority_queue <node_T> Q;            //使用优先级队列实现
     node_T cur;
     cur.v = s;
     cur.len = 0;
     Q.push(cur);
     for(int i = 1; i <= vn; i ++) dist[i] = INF;       //除源点以外的所有点的距离设置成无穷大(此处与邻接阵实现不同,临界阵赋值为到源点的距离,这里也可但是麻烦
     dist[s] = 0;
     while(! Q.empty()) {
          int v = Q.top().v;               //优先级队列使用top()
          u64_T len = Q.top().len;
          Q.pop();

         if(d[v]!=len)  continue;
          for(edge_T *ptr = adj[v]; ptr; ptr = ptr -> next) {
               int u = ptr -> v;
               u64_T w = ptr -> w;

              
               if(dist[v] + w < dist[u]) {
                    dist[u] = dist[v] + w;
                    cur.v = u;
                    cur.len = dist[u];
                    Q.push(cur);
               }
          }
     }    
}
int main() {
      int i;
      int src;
      scanf("%d %d", &vn, &en);
      for(i = 1; i <= vn; i ++) {
           adj[i] = NULL;                //初始化邻接表的指针
      }
      edgenum = 0;                       //初始化边数
      int u, v;
      u64_T w;
      for(i = 1; i <= en; i ++) {        //双向边 
           scanf("%d%d%I64u", &u, &v, &w); //最好采用此种读取方式,下边一种在某些题目中会出错
           //scanf("%d%d%llu", &u, &v, &w);
           addEdge(u, v, w);
           addEdge(v, u, w);
      }
      src = 1;
      dijkstra(src);
      return 0;
}

你可能感兴趣的:(dijkstra)