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];

        }


    }





}