最短路——Dijkstra算法
解决:单源最短路问题(一个源点到其余所有点的最短路问题)
堆优化复杂度:O(nlogn)
算法思想:可以理解为多米诺骨牌,先到达点t的骨牌有贡献,后到达的骨牌无贡献。利用贪心的思想
步骤:源点s
1:首先将所有的点分为两类,一类是已经找到到源点s的最短路的点S,一类是没有找到T。起初S中只有源点s
2:在s的所有直连邻居中,找到最近的邻居u,u肯定是骨牌最首先到达的,那么记录dis[u]的值,然后再在u的直连邻居中+dis[u]的直连邻居比较,找到最小的值v,记录dis[v],下次再在v的直连邻居中+dis[v]和s的直连邻居以及u的直连邻居+dis[u]中找最小值,如此查找,直到找到所有的结点
const int N=1e5+10; const int INF=1e9; struct edge{ int from,to,w; edge(int a,int b,int c){ from=a,to=b,w=c; } }; struct s_node{ int id,n_dis;//id:结点号 n_dis:这个结点到起点的一个距离 s_node(int b,int c) { id=b; n_dis=c; } bool operator<(const struct s_node &a) const{ return n_dis>a.n_dis; } }; int dis[N];//记录所有结点到源点的最短距离 bool done[N];//true表示已经找到该结点的最短路 int pre[N]; vector<struct edge> E[N]; int n; void Print_path(int s,int t){ if(s==t) { cout<<s<<" "; return ; } Print_path(s,pre[t]); cout<<t<<" "; } void dijkstra(int s){//s表示源点 for(int i=1;i<=n;i++) dis[i]=INF,done[i]=false; dis[s]=0; priority_queue<struct s_node>q; while(!q.empty()){ s_node u=q.top();q.pop(); if(done[u.id]) continue;//若是没有这一行,大概率会超时 done[u.id]=true; for(int i=0;i<E[u.id].size();i++){ struct edge y=E[u.id][i]; if(done[y.to]) continue; if(dis[y.to]>y.w+u.n_dis){ dis[y.to]=y.w+u.n_dis; q.push(s_node(y.to,dis[y.to])); pre[y.to]=u.id; } } } }
作者:孙建钊
出处:http://www.cnblogs.com/sunjianzhao/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。