这里我把Dijkstra的邻接表+优先队列的方法封装成了一个类,感觉挺好用的。
#include <cstdio> #include <cstring> #include <vector> #include <algorithm> #include <queue> using namespace std; const int INF = 0x3f3f3f3f; const int maxn = 20005; struct Edge { int from, to, dist; Edge(int u,int v,int d) { from = u; to = v; dist = d; } }; struct HeapNode { int d, u; HeapNode(int _d,int _u) { d = _d; u = _u; } bool operator < (const HeapNode& rhs) const { return d > rhs.d; } }; struct Dijkstra { int n,m; vector<Edge> edges; vector<int> G[maxn]; bool done[maxn]; //是否被永久标记 int d[maxn]; //s到各个点的距离 int p[maxn]; //最短路上的一条弧 void init(int n) { this->n = n; for(int i = 0; i < n; i++) { G[i].clear(); } edges.clear(); } void AddEdge(int from,int to,int dist) { edges.push_back(Edge(from,to,dist)); m = edges.size(); G[from].push_back(m-1); } void dijkstra(int s) { priority_queue<HeapNode> Q; for(int i = 0; i < n; i++) { d[i] = INF; } d[s] = 0; memset(done,0,sizeof(done)); Q.push(HeapNode(0,s)); while(!Q.empty()) { HeapNode x = Q.top(); Q.pop(); int u = x.u; if(done[u]) { continue; } done[u] = true; for(int i = 0; i < G[u].size(); i++) { Edge& e = edges[G[u][i]]; if(d[e.to] > d[u] + e.dist) { d[e.to] = d[u] + e.dist; p[e.to] = G[u][i]; Q.push(HeapNode(d[e.to], e.to)); } } } } }; int main() { Dijkstra dij; int t,cas = 1; int n,m; int u,v,dist; int s,e; scanf("%d",&t); while(t--) { scanf("%d%d%d%d",&n,&m,&s,&e); dij.init(n); for(int i = 0; i < m; i++) { scanf("%d%d%d",&u,&v,&dist); dij.AddEdge(u,v,dist); dij.AddEdge(v,u,dist); } dij.dijkstra(s); printf("Case #%d: ",cas++); if(dij.d[e] == INF) { printf("unreachable\n"); }else { printf("%d\n",dij.d[e]); } } return 0; }