考研机试真题--最短路径问题--浙江大学

本文介绍了一种求解给定图中两点间最短路径及最小花费的算法实现,采用弗洛伊德算法进行求解,并通过具体示例展示了如何通过输入顶点和边的信息来获得从起点到终点的最短距离及其对应的最小花费。

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

题目:
题目描述
给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
输入描述:
输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点t。n和m为0时输入结束。
(1 < n <= 1000, 0 < m < 100000, s != t)
输出描述:
输出 一行有两个数, 最短距离及其花费。
示例1
输入
复制
3 2
1 2 5 6
2 3 4 5
1 3
0 0
输出
复制
9 11

链接:
https://www.nowcoder.com/practice/e372b623d0874ce2915c663d881a3ff2?tpId=40&tqId=21483&tPage=1&rp=1&ru=/ta/kaoyan&qru=/ta/kaoyan/question-ranking

代码:

#include <iostream>
#include <fstream>
using namespace std;
const int maxn = 1010;
const int maxm = 100010;
#define INF 999999

int GLen[maxn][maxn], GCost[maxn][maxn];
int n;

void floyd(){
    for(int k = 1; k <= n; ++k){
        for(int i = 1; i <= n; ++i){
            for(int j = 1; j <= n; ++j){
                if(GLen[i][j] > GLen[i][k] + GLen[k][j]){
                    GLen[i][j] = GLen[i][k] + GLen[k][j];
                    GCost[i][j] = GCost[i][k] + GCost[k][j];
                }
                else if(GLen[i][j] == GLen[i][k] + GLen[k][j] && GCost[i][j] > GCost[i][k] + GCost[k][j]){
                    GCost[i][j] = GCost[i][k] + GCost[k][j];
                }
            }
        }
    }
}

//floyd算法
int main(){
//    freopen("a.txt", "r", stdin);
    int m, start, end, a, b, l, c;
    while(cin >> n >> m && !(n == 0 && m == 0)){

        for(int i = 1; i <= n; ++i){
            for(int j = 1; j <= n; ++j){
                if(i == j){
                    GLen[i][j] = GCost[i][j] = 0;
                }
                GLen[i][j] = GCost[i][j] = INF;
            }
        }

        for(int i = 0; i < m; ++i){
            cin >> a >> b >> l >> c;
            if(GLen[a][b] > l){
                GLen[a][b] = GLen[b][a] = l;
                GCost[a][b] = GCost[b][a] = c;
            }
            else if(GLen[a][b] == l && GCost[a][b] > c){
                GCost[a][b] = GCost[b][a] = c;
            }
        }
        cin >> start >> end;
        floyd();
        cout << GLen[start][end] << " " << GCost[start][end] << endl;
    }


    return 0;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值