最短路径--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;
}
