MOOC浙大数据结构 — 07-图6 旅游规划 (25分)

本文介绍了一个最短路径算法的应用案例,旨在帮助用户找到从出发地到目的地之间既最短又最经济的自驾路线。通过使用Dijkstra算法并进行适当修改以考虑路径成本,程序能够有效地解决这一问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


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

输入格式:

输入说明:输入数据的第1行给出4个正整数NNMMSSDD,其中NN2\le N\le 5002N500)是城市的个数,顺便假设城市的编号为0~(N-1N1);MM是高速公路的条数;SS是出发地的城市编号;DD是目的地的城市编号。随后的MM行中,每行给出一条高速公路的信息,分别是:城市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 <cstdio>
#include <vector>
#include <algorithm>

#define MAX 500 + 10
#define INF 0x3fffffff

using namespace std;

typedef struct {
    int l;
    int c;
} Edge;

Edge MGraph[MAX][MAX];

int minCost;
int collected[MAX];
int dist[MAX];
vector<int> tempPath;
vector<int> path[MAX];
vector<int> bestPath;

void initMGraph() {
    for( int i = 0; i < MAX; i++ ) {
        for( int j = 0; j < MAX; j++ ) {
            MGraph[i][j].l = MGraph[i][j].c = INF;
            MGraph[j][i].l = MGraph[j][i].c = INF;
        }
    }
}

void Dijkstra( int n, int start ) {
    fill( dist, dist + MAX, INF );
    dist[start] = 0;
    for( int i = 0; i < n; i++ ) {
        int u = -1, MIN = INF;
        for( int j = 0; j < n; j++ ) {
            if( collected[j] == 0 && dist[j] < MIN ) {
                u = j;
                MIN = dist[j];
            }
        }
        if( u == -1 ) return;
        collected[u] = 1;
        for( int v = 0; v < n; v++ ) {
            if( collected[v] == 0 && MGraph[u][v].l != INF ) {
                if( dist[u] + MGraph[u][v].l < dist[v] ) {
                    dist[v] = dist[u] + MGraph[u][v].l;
                    path[v].clear();
                    path[v].push_back( u );
                } else if( dist[u] + MGraph[u][v].l == dist[v] ) {
                    path[v].push_back( u );
                }
            }
        }
    }
}

void DFS( int v, int s ) {
    if( v == s ){       //递归边界,到达起点
        int sum = 0;
        tempPath.push_back( s );
        for(int i = tempPath.size()-1;i;i--){
            sum += MGraph[tempPath[i]][tempPath[i-1]].c;
        }
        if(sum>0&&sum<minCost){
            bestPath = tempPath;
            minCost = sum;
        }
        tempPath.pop_back();
        return;
    }
    tempPath.push_back(v);
    for(int i = 0;i < path[v].size();i++){
        DFS( path[v][i], s );
    }
    tempPath.pop_back();
}
int main() {
    //freopen( "123.txt", "r", stdin );
    initMGraph();
    int n, m, s, d;
    minCost = 0x3fffffff;
    scanf( "%d%d%d%d", &n, &m, &s, &d );

    int a, b, length, cost;
    for( int i = 0; i < m; i++ ) {
         scanf( "%d%d%d%d", &a, &b, &length, &cost );
         MGraph[a][b].l = length;
         MGraph[a][b].c = cost;
         MGraph[b][a].l = length;
         MGraph[b][a].c = cost;
    }

    Dijkstra( n, s );
    DFS( d, s );
    ////for( int i = 0; i < n; i++ ) printf( "%d ", dist[i] );
    //printf( "\n" );
    //for( int i = 0; i < bestPath.size(); i++ ) printf( "%d ", bestPath[i] );
    //printf( "\n" );
    printf( "%d %d", dist[d], minCost );
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值