优先队列优化dij算法通用模板

例题链接

分析:迪杰斯特拉算法的核心思想就是每次选择最短的距离,用这个最短距离来更新相邻顶点的最短距离,并且在更新完毕后这个最短距离不需要再考虑,而优先队列恰好契合迪杰斯特拉算法的要求,用来优化正合适

优化后的时间复杂度为O(E log V)。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int inf=1<<30;
 4 typedef long long ll;
 5 const double pi=acos(-1);
 6 const int mod=1e9+7;
 7 const int maxn=1e5+7;
 8 int n,p,k;
 9 typedef pair<int ,int> P;
10 struct edge{
11     int to,cost;
12     edge(int y,int z):to(y),cost(z){}
13 };
14 int  dis[maxn];//用来记录从顶点出发到各个点的最短距离
15 vector<edge> g[maxn];
16 void dij(int p){
17     priority_queue<P,vector<P>,greater<P>> que;//优先队列默认从大到小,更改为从小到大
18     fill(dis,dis+n+1,inf);//一步步更新一定要记得一开始赋为无穷大
19     dis[p]=0;
20     que.push(P(0,p));
21     while(!que.empty()){
22         P p=que.top();que.pop();
23         int v=p.second;
24         if(dis[v]<p.first) continue;//当取出的最小值不是最短距离的话,就丢弃这个值(因为我们本意是用最短距离来不断更新)
25         for(int i=0;i<g[v].size();i++){
26             edge e=g[v][i];
27             if(dis[e.to]>dis[v]+e.cost){
28                 dis[e.to]=dis[v]+e.cost;
29                 que.push(P(dis[e.to],e.to));
30             }
31         }
32     }
33 }
34 int main(){
35     scanf("%d%d%d",&n,&p,&k);
36     for(int i=1;i<n;i++){
37         int x,y,z;scanf("%d%d%d",&x,&y,&z);
38         g[x].push_back(edge(y,z));
39         g[y].push_back(edge(x,z));
40     }
41     dij(p);
42     sort(dis+1,dis+n+1);
43     cout<<dis[k+1]<<endl;
44     return 0;
45 }

原文地址:https://www.cnblogs.com/qingjiuling/p/10372123.html

时间: 2024-08-30 07:52:09

优先队列优化dij算法通用模板的相关文章

优先队列优化dij算法

之前已经弄过模板了,但那个复杂一点,这个就是裸的dij,用起来更方便 输入格式:n,m,s,d分别是点数,边数,起点,终点 之后m行,输入x,y,z分别是两点即权值 题目链接:https://www.luogu.org/problemnew/show/P1339 1 #include <bits/stdc++.h> 2 using namespace std; 3 const int inf=1<<30; 4 typedef long long ll; 5 typedef pair

poj 1511 优先队列优化dijkstra *

题意:两遍最短路 链接:点我 注意结果用long long 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 #include<map> 8 using namespace std; 9 #define MOD 1000000007 1

最短路算法模板合集(Dijkstar,Dijkstar(优先队列优化), 多源最短路Floyd)

再开始前我们先普及一下简单的图论知识 图的保存: 1.邻接矩阵. G[maxn][maxn]; 2.邻接表 邻接表我们有两种方式 (1)vector< Node > G[maxn]; 这个是之前就定义了图的大小了,再下面使用的时候就不用对图的大小进行申请了, 但是因为是直接申请了大小 要对图进行初始化,因此可能在某些题目中这样使用的话会超时 (2)vector< vector<Node> > G; 这个是未定义大小,但是在使用之前要对其的大小内存进行申请. G.resi

poj 3013 Big Christmas Tree (dij+优先队列优化 求最短路)

模板 题意:给你一个图,1总是为根,每个边有单位价值,每个点有权重. 每条边的价值 = sum(后继节点权重)*边的单位价值. 求树的最小价值,即构成一棵树的n-1条边的最小价值. 算法: 1.因为每个边的价值都要乘以后来访问的节点的权重,而走到后来访问的点必经过这条边. 实际上总价值就是  到每个点的最短路径*这个点的权重. 2.但是这个题 数据量真的太大了,50000个点,50000条边. 写普通的dij算法tle. 必须加优先队列优化- - 据说spfa也能过,但是spfa算法不稳定- -

最短路--dijkstra+优先队列优化模板

不写普通模板了,还是需要优先队列优化的昂 1 #include<stdio.h> //基本需要的头文件 2 #include<string.h> 3 #include<queue> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 typedef pair<int,int> pii; 8 const int INF=0x3f3f3f3f; 9 10 11

dijkstra模板(好像是斐波那契额堆优化,但我为什么看起来像优先队列优化,和spfa一样)

/* Dijkstra的算法思想: 在所有没有访问过的结点中选出dis(s,x)值最小的x 对从x出发的所有边(x,y),更新 dis(s,y)=min(dis(s,y),dis(s,x)+dis(x,y)) */ #include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <vector> using namespace std; cons

配对堆优化Dijkstra算法小记

关于配对堆的一些小姿势: 1.配对堆是一颗多叉树. 2.包含优先队列的所有功能,可用于优化Dijkstra算法. 3.属于可并堆,因此对于集合合并维护最值的问题很实用. 4.速度快于一般的堆结构(左偏树,斜堆,随机堆--),具体时间复杂度: 合并(Merge):$O(1)$: 插入(Insert/Push):$O(1)$: 修改值(Change):$O(1) \sim O(\log n)$: 取出维护的最值(Top):$O(1)$: 弹出堆顶元素(Pop):$O(\log n)$: 我们依然拿洛

【基本算置顶】各大算法&amp;&amp;数据结构模板

板子,全是板子 更新日志(从2018.11.19开始) 2018.12.02 : 更新了数据结构->扫描线 2018.11.22 : 更新了数据结构->平衡树->FHQ Treap->维护区间操作 2018.11.20 : 更新了数论->博弈论->nim游戏 2018.11.20 : 更新了数据结构->平衡树->FHQ Treap 观摩本蒟蒻板子库的大佬数: 不断更新 一.数论 1.快速幂 2.欧拉函数 3.乘法逆元(线性求逆) 4.线性筛素数 5.扩展欧几

HDU - 3790 最短路径问题(Dijkstra+优先队列优化)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3790 题意:中文题(边被赋予两种属性,一种是路径,一种是花费),然后略.(逃...... 今天看了卿学姐的视频,初尝SPFA和Dijkstra. 一个是用队列优化,一个是用优先队列优化.这道题目用这两种方法都可以. dijkstra算法思想(贪心):从距离起点最近的点开始,从这个点遍历一遍它周围的点,进行松弛操作,直到最终点. 整个的算法思想就是贪心,每次都给它形成最短路. 这道题目值得注意的是预处