您的位置:首页 > 其它

PAT 1111 —— Online Map(Dijkstra单源最短路径)

2018-03-14 13:57 435 查看

题目注意事项:

[b]迪杰斯特拉两次:[/b]

第一次求最短的路程长度【顺便记录时间用时,以判断长度相同的时候选择时间短的】

第二次求最短的路程时间【顺便记录到达每个点的最短路径所需要的点数,以判断时间相同时候选择点数少的】【注意:第一次求得时间记录需要重新初始化以免错误】

[b]直接通过 vector < int > 判断最终两条路径是否重合[/b]

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息