1. 程式人生 > >PAT 1111 —— Online Map(Dijkstra單源最短路徑)

PAT 1111 —— Online Map(Dijkstra單源最短路徑)

題目注意事項:

迪傑斯特拉兩次
  1. 第一次求最短的路程長度【順便記錄時間用時,以判斷長度相同的時候選擇時間短的】
  2. 第二次求最短的路程時間【順便記錄到達每個點的最短路徑所需要的點數,以判斷時間相同時候選擇點數少的】【注意:第一次求得時間記錄需要重新初始化以免錯誤】
直接通過 vector < int > 判斷最終兩條路徑是否重合
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using
namespace std; bool pathIsSame(const vector<int> &a, const vector<int> &b) { unsigned i = 0; for (; i < a.size() && i < b.size(); ++i) { if(a[i] != b [i]) { return false; } } return i == a.size() && i == b.size(); } int
streetLength[501][501]; int streetTime[501][501]; int main() { int N, M;//城市與街道 scanf_s("%d%d", &N, &M); for (int i = 0; i < 501; ++i) { for(int j = 0; j < 501; ++j) { if(i == j) { streetLength[i][j] = 0; streetTime[i][j] = 0
; }else { streetLength[i][j] = 99999999; streetTime[i][j] = 99999999; } } } for(int i = 0; i < M; ++i) { int v1, v2, oneWay, length, time; scanf_s("%d%d%d%d%d", &v1, &v2, &oneWay, &length, &time); streetLength[v1][v2] = length; streetTime[v1][v2] = time; if(oneWay != 1) { streetLength[v2][v1] = length; streetTime[v2][v1] = time; } } int sourceV1, destinationV2;//源點和目的地 scanf_s("%d%d", &sourceV1, &destinationV2); //--儲存每個點的最短路徑的前驅節點號 int lengthPos[501], timePos[501]; //--儲存source源點到其他點的最短路徑和時間 int lengthDis[501], timeDis[501]; for (int i = 0; i < N; ++i) { if(i != sourceV1)//先確定不是源點 { lengthDis[i] = streetLength[sourceV1][i]; timeDis[i] = streetTime[sourceV1][i]; } lengthPos[i] = -1; timePos[i] = -1; } //--S集合儲存哪些點是已經確定的最短路徑點 int LengthS[501], TimeS[501]; for (int i = 0; i < N; ++i) { LengthS[i] = 0; TimeS[i] = 0; } //--Dijkstra核心演算法(鬆弛) LengthS[sourceV1] = 1;//源點已經確定好最短路徑就是本身 TimeS[sourceV1] = 1; for (int i = 0; i < N; ++i) { if (i != sourceV1)//先確定不是源點 { int minLength = 99999999; int minLengthIndex = 0; for (int j = 0; j < N; ++j) { if (LengthS[j] == 0 && lengthDis[j] < minLength) { minLength = lengthDis[j]; minLengthIndex = j; } } LengthS[minLengthIndex] = 1; for (int j = 0; j < N; ++j) { if (j != sourceV1) { if (minLength + streetLength[minLengthIndex][j] < lengthDis[j]) { lengthDis[j] = minLength + streetLength[minLengthIndex][j]; lengthPos[j] = minLengthIndex; timeDis[j] = timeDis[minLengthIndex] + streetTime[minLengthIndex][j]; } else if (minLength + streetLength[minLengthIndex][j] == lengthDis[j] && timeDis[minLengthIndex] + streetTime[minLengthIndex][j] < timeDis[j]) {//如果路徑相同,則依賴於時間同時少的,所以放在timeDis後面 lengthDis[j] = minLength + streetLength[minLengthIndex][j]; lengthPos[j] = minLengthIndex; timeDis[j] = timeDis[minLengthIndex] + streetTime[minLengthIndex][j]; } } } } } //--最短路徑上節點數目 int NumberOfNode[501]; //將timeDis重新初始化,再一次迪傑斯特拉,根據路徑點數量求最短時間 for (int i = 0; i < N; ++i) { if (i != sourceV1)//先確定不是源點 { timeDis[i] = streetTime[sourceV1][i]; } timePos[i] = -1; NumberOfNode[i] = 1; } //第二次迪傑斯特拉 for (int i = 0; i < N; ++i) { if (i != sourceV1)//先確定不是源點 { int minTime = 99999999; int minTimeIndex = 0; for (int j = 0; j < N; ++j) { if (TimeS[j] == 0 && timeDis[j] < minTime) { minTime = timeDis[j]; minTimeIndex = j; } } TimeS[minTimeIndex] = 1; for (int j = 0; j < N; ++j) { if (j != sourceV1) { if (minTime + streetTime[minTimeIndex][j] < timeDis[j]) { timeDis[j] = minTime + streetTime[minTimeIndex][j]; timePos[j] = minTimeIndex; NumberOfNode[j] = NumberOfNode[minTimeIndex] + 1; } else if (minTime + streetTime[minTimeIndex][j] == timeDis[j] && NumberOfNode[minTimeIndex] + 1 < NumberOfNode[j]) { timeDis[j] = minTime + streetTime[minTimeIndex][j]; timePos[j] = minTimeIndex; NumberOfNode[j] = NumberOfNode[minTimeIndex] + 1; } } } } } vector<int>shortLengthPos, shortTimePos; int temp_pos = destinationV2; shortLengthPos.push_back(temp_pos); while (lengthPos[temp_pos] != -1) { temp_pos = lengthPos[temp_pos]; shortLengthPos.push_back(temp_pos); } shortLengthPos.push_back(sourceV1); //----- temp_pos = destinationV2; shortTimePos.push_back(temp_pos); while (timePos[temp_pos] != -1) { temp_pos = timePos[temp_pos]; shortTimePos.push_back(temp_pos); } shortTimePos.push_back(sourceV1); if(pathIsSame(shortLengthPos, shortTimePos)) { cout << "Distance = " << lengthDis[destinationV2] << "; "; }else { cout << "Distance = " << lengthDis[destinationV2] << ":"; for (auto it = shortLengthPos.end() - 1; it > shortLengthPos.begin(); --it) { cout << " " << *it << " ->"; } cout << " " << *(shortLengthPos.begin()) << endl; } cout << "Time = " << timeDis[destinationV2] << ":"; for (auto it = shortTimePos.end() - 1; it > shortTimePos.begin(); --it) { cout << " " << *it << " ->"; } cout << " " << *(shortTimePos.begin()) << endl; }