题目注意事项:
迪杰斯特拉两次:
- 第一次求最短的路程长度【顺便记录时间用时,以判断长度相同的时候选择时间短的】
- 第二次求最短的路程时间【顺便记录到达每个点的最短路径所需要的点数,以判断时间相同时候选择点数少的】【注意:第一次求得时间记录需要重新初始化以免错误】
直接通过 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];
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;
}
int LengthS[501], TimeS[501];
for (int i = 0; i < N; ++i)
{
LengthS[i] = 0;
TimeS[i] = 0;
}
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])
{
lengthDis[j] = minLength + streetLength[minLengthIndex][j];
lengthPos[j] = minLengthIndex;
timeDis[j] = timeDis[minLengthIndex] + streetTime[minLengthIndex][j];
}
}
}
}
}
int NumberOfNode[501];
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;
}