題目大意:求圖上單點(diǎn)到單點(diǎn)之間的最短路。
題目分析:之前我們?cè)谕坏绬栴}上分析過了單源最短路問題的
Dijkstra算法。
使用鄰接矩陣實(shí)現(xiàn)的Dijkstra算法的時(shí)間復(fù)雜度是O(|V|^2)。使用鄰接表的話,更新最短距離只需要更新每一條邊即可,因此這部分的時(shí)間復(fù)雜度是O(|E|)。但是每次要枚舉所有的頂點(diǎn)來查找下一個(gè)使用的頂點(diǎn),因此最終復(fù)雜度還是O(|V|^2)。在|E|比較小時(shí),大部分經(jīng)歷放在了查找下一次要是用的頂點(diǎn)上,因此需要使用合適的數(shù)據(jù)結(jié)構(gòu)對(duì)其進(jìn)行優(yōu)化。
需要優(yōu)化的是數(shù)值的插入(更新)和取出最小值兩個(gè)操作,因此使用堆就可以了。把每個(gè)頂點(diǎn)當(dāng)前的最短距離用堆維護(hù),在更新最短距離時(shí),把對(duì)應(yīng)的元素往根的方向移動(dòng)以滿足堆的性質(zhì)。而每次從堆中取出的最小值就是下一次要使用的頂點(diǎn)。這樣堆中元素共有O(|V|)個(gè),更新和取出數(shù)值的操作有O(|E|)次,因此整個(gè)算法的復(fù)雜度是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是頂點(diǎn)的編號(hào)
int V, dist[maxn];
vector<P> G[maxn];
void dijkstra(int s) {
//通過指定greater<P>參數(shù),堆按照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)
評(píng)論(0) 編輯 收藏 引用 所屬分類:
解題報(bào)告