题目大意:有了一张自驾旅游路线图,你会知道城市间的高速公路长度、以及该公路要收取的过路费。现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径。如果有若干条路径都是最短的,那么需要输出最便宜的一条路径。
分析:这是一道要用迪杰斯特拉算法解决的最短路问题。用两个二维数组存储长度和费用,两个一维数组存储最小的长度和费用。
两种情况下要进行一维数组的更新。第一.当从当前节点q到节点j的距离小于原先的到节点j的最小距离,那么对于lowdis[j]和lowmoney[j]进行更新。第二.从当前节点q到节点j的距离等于原先的到节点j的最小距离,但从当前节点q到节点j所花费的钱要少于原先到节点j的钱,则对上述两个二维数组进行更新。
注意:初始的两个二维数组需要初始化为一个很大的值,也就是INF。
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int M = 1000;
const int INF = 0x3f3f3f3f;
int n, m, s, d;
int mp1[M][M], mp2[M][M], lowdis[M], lowmoney[M]; //mp1存储长度 mp2存储费用
bool vis[M] = {false};
void Dijkstra()
{
vis[s] = true;
for(int i = 0; i < n; i++)
{
lowdis[i] = mp1[s][i];
lowmoney[i] = mp2[s][i];
}//lowdis和lowmoney两个数组初始化为从点s出发到其余点的距离和费用
for(int i = 0; i < n - 1; i++)
{
int min_n = INF, q = -1;
for(int j = 0; j < n; j++)
{
if(!vis[j] && lowdis[j] < min_n)
{
min_n = lowdis[j];
q = j;
}
}//找到从当前点到其余点的距离中的最小值
vis[q] = true;//更新状态
for(int j = 0; j < n; j++)
{
if(mp1[q][j] < INF)//寻找从q点出发的距离最短的点
{
if(lowdis[q] + mp1[q][j] < lowdis[j])
{
lowdis[j] = lowdis[q] + mp1[q][j];
lowmoney[j] = lowmoney[q] + mp2[q][j];
}
else if(lowdis[q] + mp1[q][j] == lowdis[j])
{
if(lowmoney[q] + mp2[q][j] < lowmoney[j])
{
lowdis[j] = lowdis[q] + mp1[q][j];
lowmoney[j] = lowmoney[q] + mp2[q][j];
}
}
}
}
}
}
int main()
{
cin >> n >> m >> s >> d;
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
if(i == j)
mp1[i][j] = mp2[i][j] = 0;
else
mp1[i][j] = mp2[i][j] = INF;
}
}
for(int i = 1; i <= m; i++)
{
int a, b, c, f;
cin >> a >> b >> c >> f;
mp1[a][b] = mp1[b][a] = c;
mp2[a][b] = mp2[b][a] = f;
}
Dijkstra();
cout << lowdis[d] << " " << lowmoney[d] << endl;
return 0;
}