优先队列优化Dijkstra-hdu2066
2017-07-24 13:29
309 查看
Dijkstra
Dijkstra算法适用于边权为正的情况,用于计算正权图上的单源最短路(Single-Source Shortest Paths,SSSP),即从单个源点出发,到所有结点的最短路。该算法同时适用于有向图和无向图。时间复杂度为O(n^2),n是节点数。算法思想:
首先初始化dist为INF=0x3f3f3f3f,dist[源点]=0,然后循环n次,在所有未标号的结点中,选出dist值最小的结点x,给结点x标记,对从x结点出发的所有边(x,y)更新dist[y]。
该算法也能很方便的打印出结点1到所有结点的最短路本身,只需在更新dist[y]时用path数组维护从最短路到该结点的父结点的下标即可。
现在算法竞赛中可能一般的Dijkstra写法会被卡时间,n^2的复杂度还是很高的。所以我们写正权的最短路问题最好还是用邻接表+堆优化(优先队列优化)的Dijkstra。
Dijksta算法中,如果我们采用的是邻接矩阵来存边,空间浪费大,时间复杂度也高,所以我们考虑优化它,采用邻接表来存储,其次我们可以用优先队列来排序大小,其时间复杂度大大降低。
我看网上有些人是自己手写小根堆实现,这当然是更好的。我问了下学长,应该是不会卡手写小根堆和STL优先队列之间的差距,而优先队列的写法更简洁,所以我还是选优先队列来写。
我以hdu2066为模板来实现优先队列优化的Dijkstra
hdu2066
这题不是很难,把根看成源点,将其到车站的距离置为0,然后直接Dijkstra,最后取所有终点的最小值即可。具体优化过程和题解看代码注释
#include <bits/stdc++.h> using namespace std; const int INF = 0x3f3f3f3f; const int maxn = 1e3+5; int t,s,d; struct Edge{ int to,len; //存储边信息,to是到的点,len是时间 }; vector<Edge> edge[maxn]; //edge[i]记录与i点相连的边 //把i点和dist[i]打包放入优先队列。 //这里要注意pair是按照第一个元素的大小排序,如果相同才按照第二个,所以我们要把dist[i]包装在第一个元素上。 typedef pair<int,int> P; int dist[maxn]; //dist[i]记录从源点到i点的最短时间 void init() //初始化 { for(int i=0;i<maxn;i++) edge[i].clear(); memset(dist,INF,sizeof(dist)); } void Dijkstra() { priority_queue<P,vector<P>,greater<P> >pq; P p; Edge tmp; dist[0]=0; //源点dist置0 pq.push(P(0,0)); //源点加入队列 while(!pq.empty()) { p = pq.top(),pq.pop(); int u = p.second; //得到当前节点 for(int i=0;i<edge[u].size();i++) //遍历与当前节点相连的节点 { tmp = edge[u][i]; if(dist[tmp.to]>dist[u]+tmp.len) { dist[tmp.to] = dist[u]+tmp.len; //更新 pq.push(P(dist[tmp.to],tmp.to)); } } } } int main() { while(~scanf("%d%d%d",&t,&s,&d)) { init(); int a,b,c; Edge tmp; while(t--) { scanf("%d%d%d",&a,&b,&c); //建边 tmp.to = b,tmp.len = c; edge[a].push_back(tmp); tmp.to = a,tmp.len = c; edge[b].push_back(tmp); } while(s--) { scanf("%d",&a); //源点(家)和车站相连 tmp.to = a,tmp.len = 0; edge[0].push_back(tmp); tmp.to = 0,tmp.len = 0; edge[a].push_back(tmp); } Dijkstra(); int ans = INF; while(d--) { scanf("%d",&a); if(dist[a]<ans) ans = dist[a]; //得到所有终点的最短时间 } printf("%d\n",ans); } return 0; }
相关文章推荐
- Dijkstra算法优先队列优化
- P - The Shortest Path in Nya Graph(拆点+dijkstra优先队列优化)
- hdu 2066最短路 dijkstra 及其优先队列优化
- usaco2.4 comehome 最短路 Floyd, Dijkstra, Dijkstra优先队列优化
- hdu 1874 畅通工程续 (Dijkstra + 优先队列优化)
- POJ1724 ROADS(深搜DFS,最短路,dijkstra,用优先队列优化)
- Dijkstra(n log(n))优先队列优化+链式前向星
- uva10986 优先队列优化的Dijkstra
- 蓝桥杯 算法训练 最短路 【SPFA队列优化 + dijkstra优先队列优化】
- HDU ~ 2544 ~ 最短路 (Dijkstra模板,常规版 and 优先队列优化版)
- 【原创】最短路模板 Floyd,优先队列优化dijkstra,SPFA
- dijkstra的优先队列优化
- hdu 2680 dijkstra 使用优先队列优化
- hdu1874(dijkstra解法优先队列优化)
- Dijkstra优先队列优化
- UVa 10986 Sending email / 优先队列优化dijkstra
- poj 2387(Dijkstra优先队列优化)
- Dijkstra普通算法及优先队列优化
- 【bzo1579】拆点+dijkstra优先队列优化+其他优化
- 最短路练习10/poj/1511 Invitation Cards ,(两次spfa),(单源最短路,优先队列优化的Dijkstra)