HDU3790-最短路径问题

 

题目链接:点击打开链接

Problem Description

给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。

 

 

Input

输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点。n和m为0时输入结束。
(1<n<=1000, 0<m<100000, s != t)

 

 

Output

输出 一行有两个数, 最短距离及其花费。

 

 

Sample Input

 

3 2 1 2 5 6 2 3 4 5 1 3 0 0

 

 

Sample Output

 

9 11

 

 

 

思路:最短路模板题,涉及两个标尺,可以保险的先保存路径,再计算,这个可以直接算。看注释。

 

 

 

AC代码:

 

#include<iostream>
#include<algorithm>
using namespace std;
const int MAXV = 1010;
const int INF = 0x3f3f3f;

int d[MAXV], G[MAXV][MAXV];//矩阵
int c[MAXV], cost[MAXV][MAXV];//花费
int n, m, st, ed;

void dijsktra(int st) {
    bool vis[MAXV] = {false};
    fill(d, d + MAXV, INF);//注意这里的初始化
    fill(c, c + MAXV, INF);
    d[st] = 0;
    c[st] = 0;
    for(int i = 1; i <= n; i++) {//模板
        int u = -1, MIN = INF;
        for(int j = 1; j <= n; j++) {
            if(vis[j] == false && d[j] < MIN) {
                u = j;
                MIN = d[j];
            }
        }
        if(u == -1) return;
        vis[u] = true;
        for(int v = 1; v <= n; v++) {
            if(vis[v] == false && G[u][v] != INF) {
                if(d[u] + G[u][v] < d[v]) {//短的话,都更新
                    d[v] = d[u] + G[u][v];
                    c[v] = c[u] + cost[u][v];
                } else if(d[u] + G[u][v] == d[v] && c[u] + cost[u][v] < c[v]) {//相等的话,更新花费
                    c[v] = c[u] + cost[u][v];
                }
            }
        }
    }
}

int main() {
    int a, b, w, p;
    while(scanf("%d %d", &n, &m) != EOF, n || m) {
        fill(G[0], G[0] + MAXV * MAXV, INF);
        fill(cost[0], cost[0] + MAXV * MAXV, INF);
        while(m--) {
            scanf("%d %d %d %d", &a, &b, &w, &p);
            if(G[a][b] > w) {//最大的坑点。可能有多条路径。!!!!!
                G[a][b] = G[b][a] = w;
                cost[a][b] = cost[b][a] = p;
            } else if(G[a][b] == w && cost[a][b] > p) {
                cost[a][b] = cost[b][a] = p;
            } 
        }
        scanf("%d %d", &st, &ed);
        dijsktra(st);
        printf("%d %d\n", d[ed], c[ed]);
    }
    return 0;
}

 

posted @ 2018-04-27 22:52  Frontierone  阅读(88)  评论(0编辑  收藏  举报