Dijkstra算法–变型题的求解
//Dijkstra算法用来求最短距离 已经实现了
//做题题型有变化,需要处理升级版
/*
//碰到有两条及以上可以达到最短距离的路径,题目就会给出第二标尺
//第一标尺是距离,要求在所有最短路径中选择第二标尺最优的一条路径。
//
// 第二标尺常见的有下面3种出题方法或组合
// 1.给每条边再增加一个边权(比如花费),然后要求在最短路径有
// 多条时要求路径上的花费之和最小。(或者最大)
// 2.给每个点增加一个点权(例如每个城市能收集到的物资),然后在
// 最短路径有多条时要求路径上的点权之和最大(或最小)
// 3.直接问有多少条最短路径。
// 对以上3中问题,都只需要增加一个数组来存放新增的边权或点权或
// 最短路径条数,然后在Dijkstra算法中修改优化d[v]的那个步骤即可,其他
// 部分不需要改动。
*/
//1.新增边权
//初始时,只有c[s]=0,其余c[u]均为INF
for(int v=0;v<n;v++)
{
//如果v未访问 && u能到达v
if( vis[v]==false && G[u][v]!=INF )
{
//以u为中介点可以使d[v]更优
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[v]=c[u]+cost[u][v];
}
}
}
//2.新增点权
//这里要注意,我们要求物资的最大情况了
//用weight[u]表示城市u中的物资数目(由题目输入)
//增加一个数组w[],令从起点s达到顶点u可以收集到的最大物资为w[u]
//初始时,只有w[s]为weight[s],其余w[u]均为0
for(int v=0;v<n;v++)
{
//如果v未被访问 && u能到达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[v];
}
else if( d[u] + G[u][v] == d[v] && w[u]+weight[v]>w[v] )
{
//最短距离相同时,看能否使w[v]更优
w[v]=w[u]+weight[v];
}
}
}
//3.求最短路径条数
//需要增加一个数组num[],令从起点s到达顶点u的最短路径条数为num[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
num[v]+=num[u];
}
}
}