ABC E WA
  • 板块学术版
  • 楼主KaguyaH
  • 当前回复3
  • 已保存回复3
  • 发布时间2021/6/6 21:48
  • 上次更新2023/11/4 22:12:56
查看原帖
ABC E WA
236807
KaguyaH楼主2021/6/6 21:48

满足 Dijkstra 条件,每次 uvu \to v 松弛对于 uu 的最小到达时间和这条边的最优通过取最大值。

最优通过时间应为使 t+1+dt+1t + 1 + \lfloor \frac d {t + 1} \rfloor 取最小值的 tt

# include <ciso646>
# include <climits>
# include <cmath>
# include <cstdio>
# include <cstring>
# include <algorithm>
# include <queue>

namespace Main {
    namespace Source {
        typedef signed int dint;
        typedef short signed int hd;
        typedef long signed int ld;
        typedef long long signed int lld;
        typedef unsigned int uint;
        typedef short unsigned int hu;
        typedef long unsigned int lu;
        typedef long long unsigned int llu;
        typedef double lf;
        typedef long double Lf;
        typedef signed char hhd;
        typedef unsigned char hhu;
        template <typename T>
        static inline const T min(const T& a, const T& b) { return b < a ? b : a; }
        template <typename T>
        static inline const T max(const T& a, const T& b) { return a < b ? b : a; }
        template <typename T> static inline T& min(T& a, T& b) { return b < a ? b : a; }
        template <typename T> static inline T& max(T& a, T& b) { return a < b ? b : a; }
    }
    using namespace Source;
    enum { N = (const uint)1e5, M = (const uint)1e5, D = (const uint)1e9, Log = 29 };
    struct road {
        uint a, b;
        uint c, d;
        uint best;
        inline const void read() { scanf("%u%u%u%u", &a, &b, &c, &d); }
        inline const uint take(const llu gt) { return c + d / (gt + 1); }
    };
    struct city {
        struct road {
            uint id;
            const road* next;
            road() : next(NULL) {}
            road(const uint id, const road* next = NULL) : id(id), next(next) {}
            compl road() { if (next) delete next; }
        };
        llu et;
        road* head;
        city() : et(ULLONG_MAX), head(NULL) {}
        compl city() { if (head) delete head; }
        inline const void add(const uint id) { head = new road(id, head); }
    };
    struct cityp {
        uint p; llu et;
        cityp() {}
        cityp(const uint p, const llu et) : p(p), et(et) {}
        friend inline const bool operator < (const cityp& a, const cityp& b)
        { return a.et > b.et; }
    };
    static uint n, m;
    static road r[M + 1];
    static city c[N + 1];
    static uint best(const uint d) {
        if (d == 0) return 0;
        lf t(sqrt(d));
        const uint ft(t + 1e-9), ct(t + 1 - 1e-9);
        const uint u(ct + d / ct < ft + d / ft ? ct : ft);
        const uint v(u + d / u);
        // printf("%u %lf %u %u\n", d, t, u, v);
        uint r(0);
        for (hu i(Log); i <= Log; --i)
            if ((r | 1 << i) <= u and (r | 1 << i) + d / (r | 1 << i) > v)
                r or_eq 1 << i;
        return r;
    }
    static inline const void solve() {
        std::priority_queue<cityp> h; h.push(cityp(1, c[1].et = 0));
        while (not h.empty()) {
            if (h.top().et not_eq c[h.top().p].et) { h.pop(); continue; }
            const uint t(h.top().p); h.pop();
            for (const city::road* i(c[t].head); i; i = i->next) {
                const llu gt(max(c[t].et, (const llu)r[i->id].best));
                if (gt + r[i->id].take(gt) < c[r[i->id].b].et)
                    h.push(cityp(r[i->id].b, c[r[i->id].b].et = gt + r[i->id].take(gt)));
            }
        }
    }
    static inline const void main() {
        scanf("%u%u", &n, &m);
        for (register uint i(1); i <= m; ++i)
            r[i].read(), r[i].best = best(r[i].d), c[r[i].a].add(i);
        solve();
        printf("%lld\n", c[n].et);
    }
}

signed int main() { Main::main(); return 0; }
2021/6/6 21:48
加载中...