九度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编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示