迪杰斯特拉算法_优化版

迪杰斯特拉优化版本:vector + 优先队列

△迪杰斯特拉算法的核心:每次找距离s点最短的元素 + 松弛操作

①要用优先队列取出最短距离降低时间复杂度,用veotor减少空间

②定义一个pair类型,作为优先队列的元素。typedef pair P ,first是距离,second是边的终点

③pair类型作为优先队列的元素时,默认排序是先排序first,后再排序second。(升序)

因此,距离是first,边的终点是second,不可调换

 

#include 
#include 
#include <string.h>
#define MAX 100


using namespace std;

typedef pair<int,int> P;        //first:dis[i]  second:下标i,边的终点
vector

map[MAX]; //不能先下标后权值,因为pair先排序first后排序second int vis[MAX]; int dis[MAX]; priority_queue, greater

> q; const int INF = 0x3f3f3f3f; void Dijkstra(int s, int n){ memset(dis,INF,sizeof(dis)); memset(vis,0,sizeof(vis)); dis[s]=0; q.push(P(0,s)); //将起始点push入队列 while(!q.empty()){ P p =q.top();    //每次取最小元素 q.pop();        //出队 int u=p.second; if(vis[u]) continue; vis[u]=1; for(int i=0;i//i并不是边的终点,只是顺序存储的东西 int v=map[u][i].second; //获取边的终点v int w=map[u][i].first; //获取u到v的距离 if(!vis[v]){ if(dis[v]>dis[u]+w){ dis[v]=dis[u]+w; q.push(P(dis[v],v));       //松弛操作过的元素入队 } } } } } int main(){ int n,m,s; int u,v,w; while(scanf("%d %d %d",&n,&m,&s)!=EOF){ //顶点数n, 边数m, 起始点s for(int i=1;i<=n;i++) map[i].clear(); //清空vector 注意 vector 不能用二维数组初始化 for(int i=0;i){ scanf("%d %d %d",&u,&v,&w); map[u].push_back({w,v}); //无向图 map[v].push_back({w,u}); //有向图只push一次 } Dijkstra(s,n); for(int i=1;i<=n;i++) printf("%d ",dis[i]); } return 0; }

你可能感兴趣的:(迪杰斯特拉算法_优化版)