dijkstra算法讲解

dijkstra主要方法:

  • 分成两组:已经确定最短路、尚未确定最短路
  • 从第2组中选择路径长度最短的点放入第1组并扩展
  • 本质是贪心,只能应用于正权图
  • 普通的Djkstra算法O(N^2)
  • 堆优化的Dijkstra算法O(NlogN)-O(MlogN)

引入概念——松弛操作:

  • 原来用一根橡皮筋直接连接a、b两点,现在有一点k,使得a − > k − > b比a − > b的距离更短,则把橡皮筋改为a − > k − > b,这样橡皮筋更加松弛。
  • 代码实现:if(dis[b]>dis[k]+w[k][b]) dis[b]=dis[k]+w[k][b];

算法描述:

设起点为s,dis[v]表示从指定起点s到v的最短路径pre[v]为v的前驱,用来输出路径

1.初始化

memset(dis,+∞)
memset(vis,false);
(int v = 1 ; v <= n ; v ++ )
dis[v]=w[s][v];
dis[s]=0; pre[s]=0; vis[s]=true;

2. 松弛n−1次

(1)在没有被访问过的点中找一个相邻顶点k,使得dis[k]是最小的;

(2)k标记为已确定的最短路vis[k]=true;

(3)用for循环更新与k相连的每个未确定最短路径的顶点v(所有未确定最短路的点都松弛更新)

3.算法结束

dis[v]为s到v的最短路距离;pre[v]为v的前驱结点,用来输出路径

代码演示

以下为优化后的代码

struct edge{
   int to , nxt , w;
}a[MAXN];
void add(int u , int v , int w) {
   a[++ cnt].w = w;
   a[cnt].to = v;
   a[cnt].nxt = head[u];
   head[u] = cnt;
}
struct node{
   int id , w;
   node(int iid , int ww) {
   	id = iid;
   	w = ww;
   }
   friend bool operator<(node x , node y) {
   	return x.w > y.w;
   }
};
priority_queue<node> q;
void dijkstra() {
   memset(dis , 0x3f , sizeof(dis));
   dis[s] = 0;
   q.push(node(s , 0));
   while(!q.empty()) {
   	int u = q.top().id;
   	q.pop();
   	if (vis[u]) continue;
   	vis[u] = 1;
   	for (int i = head[u] ; i ; i = a[i].nxt) {
   		int v = a[i].to , w = a[i].w;
   		if (dis[v] > dis[u] + w) {
   			dis[v] = dis[u] + w;
   			q.push(node(v , dis[v]));
   		}
   	}
   }
}

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值