題目大意:求圖上單點到單點之間的最短路。
題目分析:之前我們在同一道問題上分析過了單源最短路問題的
Dijkstra算法。
使用鄰接矩陣實現的Dijkstra算法的時間復雜度是O(|V|^2)。使用鄰接表的話,更新最短距離只需要更新每一條邊即可,因此這部分的時間復雜度是O(|E|)。但是每次要枚舉所有的頂點來查找下一個使用的頂點,因此最終復雜度還是O(|V|^2)。在|E|比較小時,大部分經歷放在了查找下一次要是用的頂點上,因此需要使用合適的數據結構對其進行優化。
需要優化的是數值的插入(更新)和取出最小值兩個操作,因此使用堆就可以了。把每個頂點當前的最短距離用堆維護,在更新最短距離時,把對應的元素往根的方向移動以滿足堆的性質。而每次從堆中取出的最小值就是下一次要使用的頂點。這樣堆中元素共有O(|V|)個,更新和取出數值的操作有O(|E|)次,因此整個算法的復雜度是O(|E|log(V))
#include <cstdio>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
#define INF (1<<29)
const int maxn = 1010;
typedef pair<int, int> P; //first是最短距離,second是頂點的編號
int V, dist[maxn];
vector<P> G[maxn];
void dijkstra(int s) {
//通過指定greater<P>參數,堆按照first從小到大的順序取出值
priority_queue<P, vector<P>, greater<P> > que;
fill(dist, dist + V , INF);
dist[s] = 0;
while(!que.empty()) que.pop();
que.push(P(0, s));
while(!que.empty()) {
P p = que.top(); que.pop();
int u = p.second;
if(dist[u] < p.first) continue;
int sz = G[u].size();
for(int i=0;i<sz;i++) {
int to = G[u][i].second;
int cost = G[u][i].first;
if(dist[to] > dist[u] + cost) {
dist[to] = dist[u] + cost;
que.push(P(dist[to], to));
}
}
}
}
int main() {
int m;
scanf("%d%d" , &m, &V);
for(int i=0;i<V;i++) G[i].clear();
for(int i=0;i<m;i++) {
int from, to, cost;
scanf("%d%d%d" , &from, &to, &cost);
from --; to --;
G[from].push_back(P(cost, to));
G[to].push_back(P(cost, from));
}
dijkstra(0);
printf("%d\n", dist[V-1]);
return 0;
}
posted on 2015-02-13 19:38
JulyRina 閱讀(320)
評論(0) 編輯 收藏 引用 所屬分類:
解題報告