0
点赞
收藏
分享

微信扫一扫

卷麻了,新来的00后实在是太卷了...

李雨喵 2023-05-18 阅读 57

分数 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

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

#include<bits/stdc++.h>
using namespace std;
const int N=510;
int n,m,S,D;
int g[N][N],cost[N][N];//保存边和边权 
int dist[N],sum[N];//保存最短距离和最小价格 
int pre[N];//保存当前结点的上一个结点,如pre[D]=2; 
bool st[N];//用于判断当前结点有无被访问过 
void djikstra(){
    memset(dist,0x3f,sizeof dist);//初始化最短距离为无穷大 
    dist[S]=0,sum[S]=0;//初始化起点到起点的距离为0,价格为0 
    for(int i=0;i<n;i++){//朴素版djikstra算法(改) 
        int t=-1;//当前结点,一开始为-1 
        for(int j=0;j<n;j++)//遍历与当前结点距离最近的结点 
            if(!st[j]&&(t==-1||dist[j]<dist[t]))t=j;//获取与当前结点最近的结点 
        st[t]=true;//将当前结点标记为访问过 
        for(int j=0;j<n;j++){//从当前结点选择相邻的边 
            if(dist[j]>dist[t]+g[t][j]){//若满足j结点到起点的距离大于当前节点t+t和j之间距离 
                dist[j]=dist[t]+g[t][j];//更新j到起点的最小距离 
                sum[j]=sum[t]+cost[t][j];//最小距离的价格 
                pre[j]=t;//最小距离的路径 
            }
            else if(dist[j]==dist[t]+g[t][j]&&sum[j]>sum[t]+cost[t][j]){//只有当同时为最小距离且当前的价格小于之前最小距离的价格 
                sum[j]=sum[t]+cost[t][j];//更新价格 
                pre[j]=t;//更新路径 
            }
        }
    }
}
int main(){
    cin>>n>>m>>S>>D;
    memset(g,0x3f,sizeof g);//初始化每条边之间距离为无穷大 
    memset(cost,0x3f,sizeof cost);//初始化每条边之间价格为无穷大 
    while(m--){
        int c1,c2,d,c;
        cin>>c1>>c2>>d>>c;
        g[c1][c2]=g[c2][c1]=min(d,g[c1][c2]);//若有公共边取最小的那条边 
        cost[c1][c2]=cost[c2][c1]=c;//两条边之间的价格 
    }
    djikstra();//求最短距离和最小的价格,并倒序保存路径结点 
    vector<int>path;//用于输出路径结点 
    path.push_back(D);//将末结点压入 
    for(int i=D;i!=S;i=pre[i])path.push_back(pre[i]);//从末节点为当前结点开始,每次取当前结点的上一个结点 
    for(int i=path.size()-1;i>=0;i--)cout<<path[i]<<' ';//倒序输出即为路径    
    cout<<dist[D]<<' '<<sum[D];//输出最短距离和最小价格 
    return 0;
}

举报

相关推荐

0 条评论