1030 Travel Plan (30 分)(dijkstra+记录路径)

1030 Travel Plan (30 分)

A traveler's map gives the distances between cities along the highways, together with the cost of each highway. Now you are supposed to write a program to help a traveler to decide the shortest path between his/her starting city and the destination. If such a shortest path is not unique, you are supposed to output the one with the minimum cost, which is guaranteed to be unique.

Input Specification:

Each input file contains one test case. Each case starts with a line containing 4 positive integers N, M, S, and D, where N (≤500) is the number of cities (and hence the cities are numbered from 0 to N−1); M is the number of highways; S and D are the starting and the destination cities, respectively. Then M lines follow, each provides the information of a highway, in the format:

City1 City2 Distance Cost

where the numbers are all integers no more than 500, and are separated by a space.

Output Specification:

For each test case, print in one line the cities along the shortest path from the starting point to the destination, followed by the total distance and the total cost of the path. The numbers must be separated by a space and there must be no extra space at the end of output.

Sample Input:

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

Sample Output:

0 2 3 3 40

 

#include<bits/stdc++.h>
using namespace std;
int mp[510][510],dis[510],vis[510];
int money[510][510],cost[510];
int n,m,st,ed;
const int inf = 0x3f3f3f;
int pre[510];
vector<int>path;
void dfs(int v)
{
    if(v==st)
    {
        path.push_back(v);
        return;
    }
    dfs(pre[v]);
    path.push_back(v);
}
void dijkstra(int s)
{
    fill(dis,dis+510,inf);
    dis[s]=0;
    cost[s]=0;
    while(1)
    {
        int u=-1,Min=inf;
        for(int i=0;i<n;i++)
        {
            if(!vis[i]&&dis[i]<Min)
            {
                u=i;
                Min=dis[i];
            }
        }
        if(u==-1)break;
        vis[u]=1;
        for(int i=0;i<n;i++)
        {
            if(!vis[i]&&mp[u][i])
            {
                if(dis[u]+mp[u][i]<dis[i])
                {
                    dis[i]=dis[u]+mp[u][i];
                    cost[i]=cost[u]+money[u][i];
                    pre[i]=u;
                }
                else if(dis[u]+mp[u][i]==dis[i])
                {
                    if(cost[u]+money[u][i]<cost[i])
                    {
                        cost[i]=cost[u]+money[u][i];
                        pre[i]=u;
                    }
                }
            }
        }
    }
}
int main(){
    cin>>n>>m>>st>>ed;
    for(int i=0;i<m;i++)
    {
        int a,b,c,d;
        cin>>a>>b>>c>>d;
        mp[a][b]=mp[b][a]=c;
        money[a][b]=money[b][a]=d;
    }
    dijkstra(st);
    dfs(ed);
    for(int i=0;i<path.size();i++)
    {
        cout<<path[i]<<" ";
    }
    cout<<dis[ed]<<" "<<cost[ed];
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Dijkstra算法是一种单源最短路径算法,用于计算一个节点到其他所有节点的最短路径。在Dijkstra算法中,我们可以通过记录每个节点的前驱节点来记录路径。具体实现如下: 1. 初始化一个distance数组,用来记录源节点到每个节点的距离,对于源节点,距离为0,对于其他节点,距离为无穷大。 2. 初始化一个visited数组,用来记录每个节点的访问状态,对于源节点,访问状态为true,对于其他节点,访问状态为false。 3. 初始化一个predecessor数组,用来记录每个节点的前驱节点,对于源节点,前驱节点为null,对于其他节点,前驱节点为undefined。 4. 将源节点加入一个优先队列中。 5. 从优先队列中取出一个节点,标记其为已访问,遍历其所有邻居节点,如果该邻居节点未被访问,则计算源节点到该邻居节点的距离,如果该距离小于distance数组中该节点的距离,则更新distance数组和predecessor数组,并将该邻居节点加入优先队列中。 6. 重复步骤5,直到所有节点都被访问过。 7. 根据predecessor数组可以得到源节点到每个节点的最短路径。 下面是一个JavaScript实现示例: ``` function dijkstra(graph, source) { var distance = []; var visited = []; var predecessor = []; var queue = new PriorityQueue(); for (var i = 0; i < graph.length; i++) { distance[i] = Infinity; visited[i] = false; predecessor[i] = undefined; } distance[source] = 0; queue.enqueue(source, 0); while (!queue.isEmpty()) { var u = queue.dequeue(); if (visited[u]) { continue; } visited[u] = true; for (var v = 0; v < graph[u].length; v++) { if (graph[u][v] !== 0 && !visited[v]) { var alt = distance[u] + graph[u][v]; if (alt < distance[v]) { distance[v] = alt; predecessor[v] = u; queue.enqueue(v, distance[v]); } } } } return predecessor; } ``` 注:上述实现中,我们使用了一个优先队列来存储节点和节点距离,这样可以保证每次取出的是距离最小的节点,从而保证算法的正确性。你可以使用任何优先队列实现,例如JavaScript中的数组,Java中的PriorityQueue等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值