图6 旅游规划

问题

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

输入格式:

输入说明:输入数据的第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

解答 

#include <iostream>
#include <queue>
#include <vector>

const int INFINITY = 65535;


//边节点
struct ENode
{
    int V1, V2;
    int Weight;
    int Cost;

    ENode(int u, int v, int w, int c) : V1(u), V2(v), Weight(w), Cost(c) {}
};

//边终点
struct ANode
{
    //边终点下标
    int Index;
    int Weight;
    int Cost;
    ANode *Next;

    ANode() : Index(0), Weight(INFINITY), Cost(0), Next(nullptr) {}

    ANode(int index, int weight, int cost, ANode *next) : Index(index), Weight(weight), Cost(cost), Next(next) {}
};

//图顶点
struct VNode
{
    //首插法第一条边
    ANode *FirstEdge;

    VNode() : FirstEdge(nullptr) {}
};

class Graph
{
public:
    int Nv;
    int Ne;
    VNode *G;

    Graph(int n1, int n2) : Nv(n1), Ne(n2)
    {
        G = new VNode[n1];
        int u, v, w, c;
        for (int i = 0; i < n2; ++i)
        {
            std::cin >> u >> v >> w >> c;
            insert(ENode{u, v, w, c});
        }
    }

    void insert(const ENode &E) const
    {
        auto *p = new ANode(E.V2, E.Weight, E.Cost, G[E.V1].FirstEdge);
        G[E.V1].FirstEdge = p;
        p = new ANode(E.V1, E.Weight, E.Cost, G[E.V2].FirstEdge);
        G[E.V2].FirstEdge = p;
    }

    void print() const
    {
        std::cout << "*************\n";
        for (int V = 0; V < Nv; ++V)
        {
            for (auto U = G[V].FirstEdge; U; U = U->Next)
            {
                std::cout << V << '-' << '-' << U->Index << ':' << U->Weight << ' ' << U->Cost << '\n';
            }
            std::cout << "*************\n";
        }
        std::cout << '\n';
    }

    ~Graph()
    {
        delete[]G;
    }
};

//dist全部初始化为INFINITY,path全部初始化为-1
void minDist(const Graph &g, int *dist, int *path, int *cost, int S = 0)
{
    std::queue<int> Q;
    dist[S] = 0;
    cost[S] = 0;
    Q.push(S);
    while (!Q.empty())
    {
        int V = Q.front();
        Q.pop();
        for (auto U = g.G[V].FirstEdge; U; U = U->Next)
            if (dist[U->Index] >= dist[V] + U->Weight)
            {
                if (dist[U->Index] > dist[V] + U->Weight)
                {
                    dist[U->Index] = dist[V] + U->Weight;
                    cost[U->Index] = cost[V] + U->Cost;
                    path[U->Index] = V;
                    Q.push(U->Index);
                } else
                {
                    if (cost[U->Index] > cost[V] + U->Cost)
                    {
                        dist[U->Index] = dist[V] + U->Weight;
                        cost[U->Index] = cost[V] + U->Cost;
                        path[U->Index] = V;
                        Q.push(U->Index);
                    }
                }
            }
    }
}

int main()
{
    int N, M, S, D;
    std::cin >> N >> M >> S >> D;
    Graph g(N, M);
    int *dist = new int[N];
    int *path = new int[N];
    int *cost = new int[N];
    for (int i = 0; i < N; ++i)
    {
        dist[i] = INFINITY;
        cost[i] = INFINITY;
        path[i] = -1;
    }
    minDist(g, dist, path, cost, S);
//    for (int i = 0; i < N; ++i) std::cout << dist[i] << ' ';
//    std::cout << '\n';
//    for (int i = 0; i < N; ++i) std::cout << path[i] << ' ';
//    std::cout << '\n';
//    for (int i = 0; i < N; ++i) std::cout << cost[i] << ' ';
//    std::cout << '\n';
    std::cout << dist[D] << ' ' << cost[D] << '\n';
    delete[]dist;
    delete[]path;
    delete[]cost;
//     g.print();
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值