HDOJ-3790-最短路径问题 解题报告

       一道最短路问题。普通最短路问题的边只有一种权值,而此题的边要考虑两种权值。因为节点n<=1000,所以不能够使用Floyd算法,时间复杂度较高,这里使用Dijkstra算法解决。


       中文描述,题意不再赘述。只是要注意每条边都有距离和花费两种权,当且仅当两条边的距离相等时才比较花费。因为需要考虑两种权,所以算法代码要有相应的改变。另外,要考虑重边的问题,依旧要考虑两种权值。


       下面是解题代码:Dijkstra解法

#include <stdio.h>
#define N 1001
#define INF 9999999

int map[N][N];      /*距离图*/
int cost[N][N];     /*花费图*/
int dis[N];         /*起点到i的距离*/
int cos[N];         /*起点到i的花费*/
int flag[N];        /*标志变量*/
int n, m;
int s, t;

void Init();    /*初始化*/

void Read();    /*输入*/

void Dijkstra();

int main()
{
    while (~scanf("%d %d", &n, &m))
    {
        if (n == 0 && m == 0)
        {
            break;
        }
        Init();
        Read();
        Dijkstra();
        printf("%d %d\n", dis[t], cos[t]);
    }
    return 0;
}

void Init()     /*初始化*/
{
    int i, j;
    for (i=1; i<=n; ++i)
    {
        for (j=1; j<=n; ++j)
        {
            map[i][j] = cost[i][j] = INF;
        }
        dis[i] = cos[i] = INF;
        flag[i] = 0;
    }
    return;
}

void Read()     /*输入*/
{
    int i;
    int a, b, c, d;
    for (i=0; i<m; ++i)
    {
        scanf("%d %d %d %d", &a, &b, &c, &d);
        if (map[a][b] > c || (map[a][b] == c && cost[a][b] > d))    /*解决重边*/
        {
            map[a][b] = map[b][a] = c;
            cost[a][b] = cost[b][a] = d;
        }
    }
    scanf("%d %d", &s, &t);
    return;
}

void Dijkstra()
{
    int i, j, k;
    int mind, minc;
    dis[s] = cos[s] = 0;
    for (i=1; i<=n; ++i)
    {
        mind = minc = INF;
        for (j=1; j<=n; ++j)
        {
            /*多权值的比较*/
            if (flag[j] == 0 && (mind > dis[j] || (mind == dis[j] && minc > cos[j])))
            {
                mind = dis[k = j];
                minc = cos[k];
            }
        }
        flag[k] = 1;
        for (j=1; j<=n; ++j)
        {
            if (flag[j] == 0 && dis[j] > dis[k] + map[k][j])
            {
                dis[j] = dis[k] + map[k][j];
                cos[j] = cos[k] + cost[k][j];
            }
            /*当距离相同时考虑花费*/
            if (flag[j] == 0 && dis[j] == dis[k] + map[k][j] && cos[j] > cos[k] + cost[k][j])
            {
                cos[j] = cos[k] + cost[k][j];
            }
        }
    }
    return;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值