1. 程式人生 > >06-2. 旅遊規劃(25)MOOC

06-2. 旅遊規劃(25)MOOC

06-2. 旅遊規劃(25)

時間限制 400 ms
記憶體限制 65536 kB
程式碼長度限制 8000 B
判題程式 Standard

有了一張自駕旅遊路線圖,你會知道城市間的高速公路長度、以及該公路要收取的過路費。現在需要你寫一個程式,幫助前來諮詢的遊客找一條出發地和目的地之間的最短路徑。如果有若干條路徑都是最短的,那麼需要輸出最便宜的一條路徑。

輸入格式說明:

輸入說明:輸入資料的第1行給出4個正整數N、M、S、D,其中N(2<=N<=500)是城市的個數,順便假設城市的編號為0~(N-1);M是高速公路的條數;S是出發地的城市編號;D是目的地的城市編號。隨後的M行中,每行給出一條高速公路的資訊,分別是:城市1、城市2、高速公路長度、收費額,中間用空格分開,數字均為整數且不超過500。輸入保證解的存在。

輸出格式說明:

在一行裡輸出路徑的長度和收費總額,數字間以空格分隔,輸出結尾不能有多餘空格。

思路:

加上了花費之後,除了更新路徑時順帶更新花費之外,還要注意當u->v和w->v這兩條路都可以達到最短路徑的時候,需要把v的結點花費更新成這兩種方式中最少的花費。既:c[e.to] = min(c[e.to], c[v] + e.cost);接下來就是普通的最短路演算法了

/***********************************************
 * Author: fisty
 * Created Time: 2015/1/17 18:56:05
 * File Name   : 06-2.cpp
 *********************************************** */
#include <iostream>
#include <cstring>
#include <deque>
#include <cmath>
#include <queue>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <algorithm>
using namespace std;
#define Debug(x) cout << #x << " " << x <<endl
#define MAX_N 500
const int INF = 0x3f3f3f3f;
typedef long long LL;
typedef pair<int, int> P;
struct edge{
    int to;                 //下一個結點
    int cost;               //花費
    int dist;               //距離
    edge(int _to, int _cost, int _dist):to(_to), cost(_cost), dist(_dist){}
};
int N,M,S,D;                //結點個數,邊數,出發點,終點
int c[MAX_N], d[MAX_N];     //每個頂點的最小花費與距離
vector<edge> G[MAX_N];      //構圖
priority_queue<P, vector<P>, greater<P> > que;

void dijkstra(){
    memset(d, 0x3f, sizeof(d));
    memset(c, 0x3f, sizeof(c));
    d[S] = 0;                         //出發點的距離初始化
    c[S] = 0;                         //出發點的花費初始化
    que.push(P(0, S));
    while(que.size()){
        P p = que.top(); que.pop();
        int v = p.second;
        if(d[v] < p.first) continue;
        for(int i = 0;i < G[v].size(); i++){
            edge &e = G[v][i];
            if(d[e.to] > d[v] + e.dist){
                //加上了花費
                d[e.to] = d[v] + e.dist;
                c[e.to] = c[v] + e.cost;
                que.push(P(d[e.to],e.to));
            }
            if(d[e.to] == d[v] + e.dist){
                //當出現重邊的時候,需要判斷一下花費是否有更小的可能
                c[e.to] = min(c[e.to], c[v] + e.cost);
            }
        }
    }
    printf("%d %d\n", d[D], c[D]);
}
int main() {
    //freopen("in.txt", "r", stdin);
    cin.tie(0);
    ios::sync_with_stdio(false);
    cin >> N >> M >> S >> D;
    for(int i = 0;i < M; i++){
        //a -> b
        int a, b, dist, cost;
        cin >> a >> b >> dist >> cost;
        //建圖,無向圖
        G[a].push_back(edge(b, cost, dist));
        G[b].push_back(edge(a, cost, dist));
    }
    dijkstra();

    return 0;
}