最短路径--Dijstra堆优化
最短路径----Dijstra堆优化
单源最短路径(是速度最快且最稳定的算法,但不过只能求带有非负权图)
思路:
Dijstra每次需要遍历所有的点,找到一个最小值,而堆优化则是利用小顶堆的优势,每次都将距离最短的点都放在队列的顶部,则无需每次遍历所有的点,这样所需的时间就更短。
时间复杂度O(mlogn)
Code:
#include<iostream> #include<queue> #include<memory.h> #include<vector> #define mp(x,y) make_pair(x,y) using namespace std; typedef pair<int,int> PP; const int M=200005; int tot,head[M],ver[M],edge[M],ne[M];//邻接表存图 int dis[M],vis[M]; int n,m,s;//顶点数,边数,起点 //priority_queue<PP> heap;//默认是为大顶堆 priority_queue<PP,vector<PP>,greater<PP> > heap;//创建小顶堆 void add(int x,int y,int z) { ver[++tot]=y;//终点数组 edge[tot]=z;.//边权数组 ne[tot]=head[x];//下一节点数组 head[x]=tot;//头数组 } void dijstra(int s) { dis[s]=0;//起点到本身的距离为0 heap.push(mp(0,s));//将起点存放到优先队列当中 while(heap.size()) { int x=heap.top().second;//读取优先队列中的点 heap.pop();//取出刚刚读取的点 if(vis[x]) continue;//如果这个点以及读取过 就跳过 vis[x]=1;//标记刚刚读取的点 for(int i=head[x];i;i=ne[i])//遍历图 { int y=ver[i]; int w=edge[i]; if(dis[y]>dis[x]+w)//判断是否有更近的距离 { dis[y]=dis[x]+w;//更新起点到y点的距离 heap.push(mp(dis[y],y));//存放到队列当中 } } } } int main() { cin>>n>>m>>s; for(int i=1;i<=m;i++) { int u,v,w; cin>>u>>v>>w; add(u,v,w); //连接表存图 } memset(vis,0,sizeof(vis));//初始化vis // memset(dis,0x3f,sizeof(dis));//初始化dis for(int i=1;i<=n;i++) dis[i]=2147483647; dijstra(s); for(int i=1;i<=n;i++) cout<<dis[i]<<' ';//输出起点到各个点的距离 return 0; }