//Dijkstra鄰接表做法<br />//鄰接表使得計算複雜度成為O(E*n),但圖為稀疏圖時效率比鄰接矩陣高,但當圖為稠密圖時,E與n^2同階,計算複雜度最壞可到O(n^3)<br />//Dijkstra優先隊列實現(相當於堆最佳化)<br />//優先隊列的實現的Dijstra可以使得演算法在處理稠密圖時速度也比使用鄰接矩陣要快<br />//原因在於插入隊列的元素的前提是邊關係必須滿足可鬆弛條件,對於稠密圖而言,可鬆弛條件是常常不滿足的<br />//因此插入隊列的元素便比邊數少很多<br />//下面使用vector容器實現鄰接表的,因為直觀易懂<br />//G[u]存放的是與結點u鄰接的所有結點<br />//遍曆鄰接邊:for(int i = 0;i < G[u].size();++i)<br />#include<iostream><br />#include<vector><br />#include<map><br />#include<queue><br />#include<string><br />#include<cstring><br />using namespace std;<br />const int MAXN = 205;<br />const int INF = 1000000;<br />int dis[MAXN];<br />int n;//結點數量<br />typedef pair<int,int> pii;<br />struct edge//建立邊的結構體<br />{<br />int u;<br />int v;<br />int w;<br />edge(int uu,int vv,int ww)<br />{<br />u = uu;<br />v = vv;<br />w = ww;<br />}<br />};<br />int dijkstra(int st,int ed,vector<edge> G[])<br />{<br />priority_queue<pii> q;//優先隊列是預設小元素先出隊<br />for(int i = 0;i < n;++i)<br />dis[i] = (i == st ? 0 : INF);//初始化dis<br />q.push(make_pair(dis[st],st));//將起點插入隊列,pair預設是優先處理first元素,故插入優先隊列先彈出隊列的優先順序是依據dis[]大小<br />while(!q.empty())<br />{<br />pii u = q.top();<br />q.pop();<br />int x = u.second;<br />if(u.first != dis[x]) continue;//可避免結點的重複拓展,提高優先隊列處理速度。因為Dijkstra演算法對每個結點都會進行一次標號。<br />//這裡每一個元素出隊都相當於處理一次已標號結點,如果出隊的這個元素,他帶的dis,和當前的dis不相同,證明這個結點是被處理過的<br />for(int i = 0;i < G[x].size();++i)<br />{<br />int y = G[x][i].v;<br />int w = G[x][i].w;<br />if(dis[y] > dis[x] + w)<br />{<br />dis[y] = dis[x] + w;<br />q.push(make_pair(dis[y],y));<br />}<br />}<br />}<br />if(dis[ed] == INF)<br />return -1;<br />else return dis[ed];<br />}</p><p>int main()<br />{<br />//freopen("in.txt","r",stdin);<br />int t,w;<br />string u,v;<br />cin >> t;<br />while(t--)<br />{<br />n = 0;//初始化結點數目<br />int e;<br />cin >> e;<br />map<string,int> M;<br />vector<edge> G[MAXN];//鄰接表<br />for(int i = 0;i < e;++i)<br />{<br />cin >> u >> v >> w;//輸入焦點1,點2, 權值<br />if(!M.count(u))<br />M.insert(make_pair(u,n++));<br />if(!M.count(v))<br />M.insert(make_pair(v,n++));//利用map關聯容器為字串型的邊進行標號<br />edge E1(M[u],M[v],w);//初始化邊,必須調換結點才能插入vector鄰接表<br />edge E2(M[v],M[u],w);<br />G[M[u]].push_back(E1);//建立鄰接表<br />G[M[v]].push_back(E2);<br />}<br />string st,ed;<br />cin >> st >> ed;<br />if(st == ed)<br />cout << 0 << endl;<br />else if(!M.count(st) || !M.count(ed))<br />cout << -1 << endl;<br />else<br />cout << dijkstra(M[st],M[ed],G) << endl;<br />}<br />return 0;<br />}