PAT甲级1111.Online Map(30)

该博客探讨了Dijkstra算法在寻找图中两个节点间最短路径和最短时间路径的问题。通过实现两个Dijkstra变种,分别计算距离和时间,展示了如何在多条边具有不同长度和时间消耗的情况下找到最优解。最终,代码示例给出了如何输出这两个路径及其对应的总距离和总时间。
摘要由CSDN通过智能技术生成
#include <bits/stdc++.h>
using namespace std;

int n, m;
int s, t;
int g_time[510][510];
int g_leng[510][510];

int dist[510];
int distpre[510];
bool st[510];

int time_[510];
int timepre[510]; // 前驱节点
int node_n[510]; // 到达每个节点经历的节点数
bool stt[510];

int use_time, use_dist;

vector<int> dij_time() {
    memset(time_, 0x3f, sizeof time_);

    time_[s] = 0;
    for (int i=0; i<n; i++) {
        int t = -1;
        for (int j=0; j<n; j++) {
            if (!stt[j] && (t==-1 || time_[t] > time_[j])) t=j;
        }
        stt[t] = true;

        for (int j=0; j<n; j++) {
            if (stt[j] == true) continue;
            if (time_[j] > time_[t] + g_time[t][j]) { 
                time_[j] = time_[t] + g_time[t][j];
                timepre[j] = t;
                node_n[j] = node_n[t] + 1;
            }
            else if (time_[j] == time_[t] + g_time[t][j] && node_n[j] > node_n[t] + 1) {
                time_[j] = time_[t] + g_time[t][j];
                timepre[j] = t;
                node_n[j] = node_n[t] + 1;
            }
        }
    }
    use_time = time_[t];

    vector<int> path;
    int tmp = t;
    while (tmp != s) {
        path.push_back(tmp);
        tmp = timepre[tmp];
    }
    path.push_back(tmp);

    return path;
}


vector<int> dij_dist() {
    memset(dist, 0x3f, sizeof dist);
    dist[s] = 0;
    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] = true;

        for (int j=0; j<n; j++) {
            if (st[j] == true) continue;
            if ((dist[j] > dist[t] + g_leng[t][j]) || (dist[j] == dist[t] + g_leng[t][j] && g_time[t][j] < g_time[distpre[j]][j])) {
                dist[j] = dist[t] + g_leng[t][j];
                distpre[j] = t;
            }
        }
    }
    use_dist = dist[t];

    vector<int> path;
    int tmp = t;
    while (tmp != s) {
        path.push_back(tmp);
        tmp = distpre[tmp];
    }
    path.push_back(tmp);


   
    return path;

}


int main()
{
    memset(g_time, 0x3f, sizeof g_time);
    memset(g_leng, 0x3f, sizeof g_leng);


    cin >> n >> m;
    for (int i=0; i<m; i++) {
        int v1, v2, dir, length, time;
        cin >> v1 >> v2 >> dir >> length >> time;
        g_leng[v1][v2] = min(g_leng[v1][v2], length);
        g_time[v1][v2] = min(g_time[v1][v2], time);
        if (dir != 1) {
            g_leng[v2][v1] = min(g_leng[v1][v2], length);
            g_time[v2][v1] = min(g_time[v1][v2], time);
        } 

    }
    cin >> s >> t;
    vector<int> dist_path = dij_dist();
    vector<int> time_path = dij_time();

    if (dist_path == time_path) {
        printf("Distance = %d; Time = %d: ", use_dist, use_time);
        for (int i=dist_path.size()-1; i>=0; i--) {
            if (i!=0)   
                cout << dist_path[i] << " -> ";
            else cout << dist_path[i] << endl;
        }
    }
    else {
        printf("Distance = %d: ", use_dist);
        for (int i=dist_path.size()-1; i>=0; i--) {
            if (i!=0)   
                cout << dist_path[i] << " -> ";
            else cout << dist_path[i] << endl;
        }

        printf("Time = %d: ", use_time);
        for (int i=time_path.size()-1; i>=0; i--) {
            if (i!=0)   
                cout << time_path[i] << " -> ";
            else cout << time_path[i] << endl;
        }
    }

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值