BZOJ#3245

3245. 最快路线

思路:

最短路,d[i][j],表示在i号点,速度为j的最短距离,记录每次转移的状态即可

代码:

#include <bits/stdc++.h>
#define int long long
int _ = 0, Case = 1;
using namespace std;
#define all(v) begin(v),end(v)
#define nline '\n'
const int N = 550;
struct T {
    int ver, v, l;
};
vector<T> h[N];
int vis[N][N];
using PII = pair<int, int>;
PII pre[N][N];
double d[N][N];
struct S {
    int ver, v;
    double t;
    bool operator<(const S &s) const {
        return t > s.t;
    }
};
void dijkstra(int ed) {
    priority_queue<S> q;
    q.push({0, 70, 0.0});
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            d[i][j] = 1e18;
        }
    }
    d[0][70] = 0;
    while (q.size()) {
        auto [ver, v, t] = q.top();
        q.pop();
        if (vis[ver][v]) continue;
        vis[ver][v] = 1;
        for (auto [i, cv, cl] : h[ver]) {
            if (!cv) cv = v;
            double ct = cl * 1.0 / cv * 1.0;
            if (d[i][cv] > ct + t ) {
                d[i][cv] = ct + t;
                pre[i][cv] = {ver, v};
                q.push({i, cv, d[i][cv]});
            }
        }
    }
    double mmin = 1e18;
    int cv = 0;
    for (int i = 0; i < N; i++) {
        if (d[ed][i] < mmin) {
            mmin = d[ed][i];
            cv = i;
        }
    }
    vector<int> v;
    int x = ed;
    for (;;) {
        v.push_back(x);
        if (x == 0) break;
        auto [tx, ty] = pre[x][cv];
        x = tx, cv = ty;
    }
    reverse(all(v));
    for (auto i : v) cout << i << ' ';

}
void solve(int Case) {
    int n, m, d;
    cin >> n >> m >> d;
    for (int i = 1; i <= m; i++) {
        int a, b, v, l;
        cin >> a >> b >> v >> l;
        h[a].push_back({b, v, l});
    }
    dijkstra(d);

}

signed main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);
    // for (cin >> _, Case = 1; Case <= _; Case++)
    solve(Case);

    return 0;
}
posted @ 2022-06-23 16:19  指引盗寇入太行  阅读(9)  评论(0编辑  收藏  举报