#include <vector>
#include <set>
using namespace std;
typedef vector <int> vi;
typedef pair <int, int> ii;
typedef vector <ii> vii;
typedef vector <vii> vvii;
const int INF = 0x7FFFFFFF;
// 創建一個賦權鄰接表(參考樣例,具體問題可能需要適當修改,特別是對於無向圖)
// n 爲頂點數(從 0 開始標記),e 爲邊數
vvii AVLmaker (int n, int e)
{
vvii G (n);
for (int i = 0; i < e; i ++)
{
int v1, v2, d;
cin >> v1 >> v2 >> d;
G [v1].push_back (ii (v2, d));
}
return G;
}
// s 爲源點,返回 s 到各點的最短路長度,INF 表示無法到達
vi Dijkstra (const vvii& G, int s) // vvii G is the adjacent vertices list of the weighted directed graph
{
int n = G.size ();
vi D (n, INF);
set <ii> Q;
D [s] = 0;
Q.insert (ii (0, s));
while (!Q.empty ())
{
ii p = *Q.begin ();
Q.erase (Q.begin ());
int d = p.first, v = p.second;
for (int i = 0, j = G [v].size (); i < j; i ++)
{
int v2 = G [v] [i].first, d = G [v] [i].second;
if (D [v2] > D [v] + d) // notice that D [v] != INF && d != INF
{
if (D [v2] != INF)
{
Q.erase (Q.find (ii (D [v2], v2)));
}
D [v2] = D [v] + d;
Q.insert (ii (D [v2], v2));
}
}
}
return D;
}
參考來源:
TopCoder tutorials : Power up C++ with the Standard Template Library : Part II: Advanced Uses : Dijkstra by set
PS:
這個是圖論裏最基本的問題,今天終於搞定了,爲往日浪費的光陰懺悔。。Orz。。
這個實現的確很高效,在 Sicily 的某題的提交結果:
Run ID User Name Problem Language Status Run Time Run Memory Submit Time
92839 rappizit 1387 C++ Accepted 0 sec 252 KB 2007-10-31 20:20:12
===============================================================================
2007-11-28 Update:
implemented via priority_queue, faster but use more memory, and add a statement : if (v ==t) break;
#include <queue>
#include <functional>
using namespace std;
typedef vector <int> vi;
typedef pair <int, int> ii;
typedef vector <ii> vii;
typedef vector <vii> vvii;
int Dijkstra (const vvii& G, int s, int t)
{
const int INF = 0x7FFFFFFF;
int n = G.size ();
vi D (n, INF);
priority_queue < ii, vector <ii>, greater <ii> > Q;
D [s] = 0;
Q.push (ii (0, s));
while (Q.size ())
{
ii p = Q.top ();
Q.pop ();
int d = p.first, v = p.second;
if (v == t) break;
if (D [v] < d) continue;
for (int i = 0, j = G [v].size (); i < j; i ++)
{
int v2 = G [v] [i].first, d = G [v] [i].second;
if (D [v2] > D [v] + d) // D [v] != INF && d != INF
{
D [v2] = D [v] + d;
Q.push (ii (D [v2], v2));
}
}
}
return (D [t] == INF ? -1 : D [t]);
}