一般会考的不是仅仅只有一种最短路径的方式,比如有两种最短路径~
如果有这种情况,那么题目就会给出一个第二标尺(第一标尺是距离)~要求再最短路径中选择一个第二标尺最优的路径~
第二标尺常见的是以下三种出题方式或者是结合:
1、给每条边增加一个边权(例如花费),要求在最短路径有多条的时候要求路径上的花费之和最小(如果边权有其他含义,那么边权也可以是最大)
2、给每个点增加一个点权(例如每个城市搜集到的物资),然后在最短路径有多条的时候要求路径上的点权之和最大(如果点权是其他含义的话也可以是最小)
3、直接问有多少条最短路径
对于这三种出题方式,都是只需要增加一个数组来存放新增的边权或者点权或者最短路径的条数,之后在Dijkstra算法中修改优化d[v]的那个步骤就可以了~~
1、新增边权
//c[u]:从s到u的最少花费
//cost[u][v]:u->v的花费
for(int v = 0; v < n; v++){
if(vis[v] == false && G[u][v] != INF){
if(d[u] + G[u][v] < d[v]){
d[v] = d[u] + G[u][v];
c[v] = c[u] + cost[u][v];
}else if(d[u] + G[u][v] == d[v] && c[u] + cost[u][v] < c[v]){
c[v] = c[u] + cost[u][v];
}
}
}
2、新增点权
//w[u]:从s到u的最少花费
//weight[u][v]:u->v的花费
for(int v = 0; v < n; v++){
if(vis[v] == false && G[u][v] != INF){
if(d[u] + G[u][v] < d[v]){
d[v] = d[u] + G[u][v];
w[v] = w[u] + weight[u][v];
}else if(d[u] + G[u][v] == d[v] && w[u] + weight[u][v] > w[v]){
w[v] = w[u] + weight[u][v];
}
}
}
3、求最短路径条数
//num[u]:从s到u的最短路径条数
//初始化的时候num[s]=1,其余num[u]=0
for(int v = 0; v < n; v++){
if(vis[v] == false && G[u][v] != INF){
if(d[u] + G[u][v] < d[v]){
d[v] = d[u] + G[u][v];
num[v] = num[u];
}else if(d[u] + G[u][v] == d[v]){
num[v] += num[u];
}
}
}