Skip to content

11565: 【原1565】最短路径问题

题目

题目描述

author: 孙梦璇 原OJ链接:https://acm.sjtu.edu.cn/OnlineJudge-old/problem/1565

Description

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

Input Format

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

(1<n<=1000, 0<m<100000, s != t)

Output Format

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

Sample Input

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

Sample Output

9 11

BugenZhao's solution

//
// Created by BugenZhao on 2019/5/17.
//

#include <iostream>
#include <string>

using std::ios, std::cin, std::cout, std::endl, std::string;

constexpr int INF = 0x7fffffff;

int height[1001][1001];
int cost[1001][1001];

int minDist, minCost;

void dijkstra(int V, int start, int end) {
    int *distTo = new int[V + 1];
    int *costTo = new int[V + 1];
    bool *marked = new bool[V + 1]{};
    for (int i = 1; i <= V; ++i) {
        distTo[i] = height[start][i];
        costTo[i] = cost[start][i];
    }
    marked[start] = true;
    for (int i = 1; i <= V && !marked[end]; ++i) {
        int minDist = INF, v;
        for (int j = 1; j <= V; ++j) {
            if (marked[j] || minDist < distTo[j]) continue;
            minDist = distTo[j];
            v = j;
        }
        marked[v] = true;

        relax:
        for (int j = 1; j <= V; ++j) {
            if (marked[j] || height[v][j] == INF) continue;
            int newDist = distTo[v] + height[v][j];
            int newCost = costTo[v] + cost[v][j];
            if (distTo[j] > newDist) {
                distTo[j] = newDist;
                costTo[j] = newCost;
            } else if (distTo[j] == newDist) {
                if (costTo[j] > newCost)
                    costTo[j] = newCost;
            }
        }
    }
    minDist = distTo[end];
    minCost = costTo[end];
    delete[] distTo, costTo, marked;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int V, E;
    cin >> V >> E;
    for (int i = 1; i <= V; ++i) {
        for (int j = 1; j <= V; ++j) {
            if (i != j)
                height[i][j] = cost[i][j] = INF;
        }
    }

    int t1, t2, t3, t4;
    for (int i = 0; i < E; ++i) {
        cin >> t1 >> t2 >> t3 >> t4;
        if (height[t1][t2] > t3) {
            height[t1][t2] = height[t2][t1] = t3;
            cost[t1][t2] = cost[t2][t1] = t4;
        } else if (height[t1][t2] == t3 && cost[t1][t2] > t4) {
            cost[t1][t2] = cost[t2][t1] = t4;
        }
    }

    int s, t;
    cin >> s >> t;
    dijkstra(V, s, t);
    cout << minDist << ' ' << minCost << endl;
    return 0;
}

ligongzzz's solution

#include "iostream"
#include "cstdio"
#include "cstring"
using namespace std;

constexpr int max_size = 2000009;

class edge {
public:
    int to = 0;
    long long val = 0;
    long long money = 0;
    edge* next = nullptr;
};

edge* head[1009], * rear[1009];
int queue_data[max_size] = { 0 };
int queue_start = 0, queue_size = 0;

long long dis[1009] = { 0 }, cost[1009] = { 0 };

void SPFA(int from) {
    queue_data[(queue_start + queue_size) % max_size] = from;
    dis[from] = 0;
    cost[from] = 0;
    ++queue_size;
    while (queue_size) {
        auto temp = queue_data[queue_start % max_size];
        ++queue_start;
        --queue_size;
        for (auto p = head[temp]->next; p; p = p->next) {
            if (dis[temp] + p->val < dis[p->to]||
                (dis[temp] + p->val == dis[p->to] && cost[temp] + p->money < cost[p->to])) {
                dis[p->to] = dis[temp] + p->val;
                cost[p->to] = cost[temp] + p->money;
                queue_data[(queue_start + queue_size) % max_size] = p->to;
                ++queue_size;
            }
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    int n, m;
    cin >> n >> m;

    for (int i = 1; i <= 1000; ++i) {
        rear[i] = head[i] = new edge;
        dis[i] = 999999999999;
        cost[i] = 999999999999;
    }
    for (int i = 0; i < m; ++i) {
        int u, v;
        long long c, money;
        cin >> u >> v >> c >> money;
        rear[u]->next = new edge;
        rear[u] = rear[u]->next;
        rear[u]->to = v;
        rear[u]->val = c;
        rear[u]->money = money;

        rear[v]->next = new edge;
        rear[v] = rear[v]->next;
        rear[v]->to = u;
        rear[v]->val = c;
        rear[v]->money = money;
    }

    int s, t;
    cin >> s >> t;

    SPFA(s);
    cout << dis[t] << " " << cost[t];

    return 0;
}