7-9 旅游规划 (25 分)

有了一张自驾旅游路线图,你会知道城市间的高速公路长度、以及该公路要收取的过路费。现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径。如果有若干条路径都是最短的,那么需要输出最便宜的一条路径。

输入格式:
输入说明:输入数据的第1行给出4个正整数N、M、S、D,其中N(2≤N≤500)是城市的个数,顺便假设城市的编号为0~(N−1);M是高速公路的条数;S是出发地的城市编号;D是目的地的城市编号。随后的M行中,每行给出一条高速公路的信息,分别是:城市1、城市2、高速公路长度、收费额,中间用空格分开,数字均为整数且不超过500。输入保证解的存在。

输出格式:
在一行里输出路径的长度和收费总额,数字间以空格分隔,输出结尾不能有多余空格。

输入样例:

4 5 0 3
0 1 1 20
1 3 2 30
0 3 4 10
0 2 2 20
2 3 1 20

输出样例:

3 40

做这道题,刚开始没想到用三维数组,用的最朴素的方法:结构体。最近没怎么刷题,有点颓废,不过也还好,数据库和英语的期末成绩都还不错,转专业也成功了,,唉,有的时候真的有点不知道做什么,学了这么久我才发现我一直都在做题,没有什么项目经验。希望明天会更好。着重强调:dist数组存的值是起到到每个顶点的最短距离。下为我写的:

#include <iostream>
using namespace std;
#define max 501
#define infinity 65535
#define false -1
#define true 1
int FindMin(int N, int dist[], int collected[])
{
    int MinV = -1, Min = infinity, i;
    for (i = 0; i < N; i++)
    {
        if (dist[i] < Min && collected[i] == false)
        {
            MinV = i;
            Min = dist[i];
        }
    }
    return MinV;
}
void Dijstra(int N, int G[][max][2], int dist[], int S)
{
    int i;
    int collected[N];
    for (i = 0; i < N; i++)
    {
        dist[i] = G[S][i][0];
        collected[i] = false;
    }
    dist[S] = 0;
    collected[S] = true;
    while (1)
    {
        int Min = FindMin(N, dist, collected);
        if (Min == false)
            break;
        collected[Min] = true;
        for (i = 0; i < N; i++)
        {
            if (G[Min][i][0] < infinity && collected[i] == false)
            {
                if (G[Min][i][0] + dist[Min] < dist[i])
                {
                    dist[i] = G[Min][i][0] + dist[Min];
                    G[S][i][1] = G[S][Min][1] + G[Min][i][1];
                }
                else if (G[Min][i][0] + dist[Min] == dist[i] && G[S][Min][1] + G[Min][i][1] < G[S][i][1])
                //距离相等,价钱更小时
                {
                    G[S][i][1] = G[S][Min][1] + G[Min][i][1];
                }
            }
        }
    }
}
int main()
{
    int i, j;
    int N, M, S, D;
    int G[max][max][2], dist[max];
    cin >> N >> M >> S >> D;
    for (i = 0; i < N; i++)
    {
        for (j = 0; j < N; j++)
        {
            G[i][j][0] = infinity;
            G[i][j][1] = 0;
        }
    }
    for (i = 0; i < M; i++)
    {
        int origin, end, distance, cost;
        cin >> origin >> end >> distance >> cost;
        G[origin][end][0] = G[end][origin][0] = distance;
        G[origin][end][1] = G[end][origin][1] = cost;
    }
    Dijstra(N, G, dist, S);
    cout << dist[D] << " " << G[S][D][1] << endl;
    //dist数组存的是 起点到每个顶点的最短距离
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

thoroughly strive

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值