1. 程式人生 > 其它 >1030 Travel Plan (30 分)

1030 Travel Plan (30 分)

題意:給定起點和終點,給定無向圖和每一條邊的長度和花費,求出從起點到終點的最短距離,如果路徑不唯一輸出花費最少的那一條路徑,並輸出最短距離和花費。

思路:dijkstra模板題,在發現兩個路徑長度相同時,如果一條路的花費更少則需要更新花費和路徑,圖用鄰接矩陣存,鄰接表複雜度會高一些

#include <iostream>
#include <vector>
#include <cstring>

using namespace std;

#define PII pair<int, int>
#define x first
#define y second

const int N = 510;

PII g[N][N];

int n, m, s, d;
int dist[N], cost[N];
bool st[N];

vector<int> path[N];

void dijkstra(int s){
    memset(dist, 0x3f, sizeof dist);
    memset(cost, 0x3f, sizeof cost);
    
    cost[s] = dist[s] = 0;
    path[s].push_back(s);
    
    for(int i = 0; i < n; i ++){
        int t = -1;
        for(int j = 0; j < n; j ++)
            if(!st[j] && (t == -1 || dist[t] > dist[j]))
                t = j;
        
        st[t] = 1;
        for(int j = 0; j < n; j ++){
            if(dist[j] > dist[t] + g[t][j].x){
                dist[j] = dist[t] + g[t][j].x;
                cost[j] = cost[t] + g[t][j].y;
                path[j] = path[t];
                path[j].push_back(j);
            }
            if(dist[j] == dist[t] + g[t][j].x){
                if(cost[j] > cost[t] + g[t][j].y){
                    cost[j] = cost[t] + g[t][j].y;
                    path[j] = path[t];
                    path[j].push_back(j);
                }
            }
        }
    }
    
}

int main(){
    memset(g, 0x3f, sizeof g);
    cin >> n >> m >> s >> d;
    while(m --){
        int a, b, w, c;
        cin >> a >> b >> w >> c;
        g[a][b] = g[b][a] = {w, c};
    }
    
    dijkstra(s);
    
    for(int i = 0; i < path[d].size(); i ++) cout << path[d][i] << ' ';
    cout << dist[d] << ' ' << cost[d];
    
    return 0;
}