九度OJ刷题——1008:最短路径问题

题目描述:
给你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)
输出:
输出 一行有两个数, 最短距离及其花费。
样例输入:
3 2
1 2 5 6
2 3 4 5
1 3
0 0
样例输出:
9 11

这题要注意两点,第一个是可能会存在重边,当两点之间存在重边的时候,存储长度最短的那条,如果有多条最短边,则取费用最低的那条边;第二个是最大值MAX的设置,一开始我设置的是INT_MAX,结果一直WA,因为INT_MAX与其他正值相加后会溢出成为负值,使得判定条件出错,这个一定要多加小心。

源代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <iostream>
#include <cstring>
using namespace std;
 
const int N = 1001;
const int MAX = 1 << 30;
int dm[N][N];
int pm[N][N];
int minDis, minCost;
 
void dijkstra(int s, int t, int n);
 
int main(){
    int n, m;
    while(cin >> n >> m){
        if(n==0 && m==0) break;
 
        //初始化距离矩阵和费用矩阵
        for(int i=1; i<=n; i++){
            for(int j=1; j<=n; j++){
                dm[i][j] = MAX;
                pm[i][j] = MAX;
            }
        }
        for(int i=0; i<m; i++){
            int a, b, d, p;
            cin >> a >> b >> d >> p;
            //这两个判断条件是为了处理重边
            if(dm[a][b] > d){
                dm[a][b] = dm[b][a] = d;
                pm[a][b] = pm[b][a] = p;
            }
            else if(dm[a][b]==d && pm[a][b]>p){
                pm[a][b] = pm[b][a] = p;
            }
        }
        int s, t;
        cin >> s >> t;
        dijkstra(s, t, n);
        cout << minDis << ' ' << minCost << endl;
    }
     
    //system("pause");
 
    return 0;
}
 
void dijkstra(int s, int t, int n){
    //存储点s到各点的距离和费用
    int dis[N];
    int cost[N];
    for(int i=1; i<=n; i++){
        dis[i] = MAX;
        cost[i] = MAX;
    }
    //用于判断是否已经求出s点到某点的最短距离和费用
    bool visit[N];
    memset(visit, false, sizeof(visit));
    //点s到自己的距离和费用为0
    dis[s] = 0;
    cost[s] = 0;
    for(int i=0; i<n; i++){
        int min = MAX;
        int k;
        for(int j=1; j<=n; j++){
            if(!visit[j] && dis[j]<min){
                min = dis[j];
                k = j;
            }
        }
        visit[k] = true;
 
        for(int j=1; j<=n; j++){
            if(!visit[j] && dis[j]>min+dm[k][j]){
                dis[j] = min + dm[k][j];
                cost[j] = cost[k] + pm[k][j];
            }
            else if(!visit[j] && dis[j]==min+dm[k][j] && cost[j]>cost[k]+pm[k][j]){
                cost[j] = cost[k] + pm[k][j];
            }
        }
    }
    minDis = dis[t];
    minCost = cost[t];
}

  

posted on   C_haos  阅读(386)  评论(0编辑  收藏  举报
编辑推荐:
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
阅读排行:
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 我与微信审核的“相爱相杀”看个人小程序副业
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~
点击右上角即可分享
微信分享提示