zoukankan      html  css  js  c++  java
  • hdu6071[最短路+解不等式] 2017多校4

    求出所有,从2走到x所需的花费在对 t = 2*min(d1,2, d2,3) 模运算下,  所有剩余系的最短路即可(把一个点拆成 t 个点, 每个点代表一种剩余系), 知道了所有剩余系就可以凑出答案。

    dis[ 2 ][ 0 ] 到 dis[ 2 ][ t - 1 ] 代表的即为对 t 取模的所有剩余系的最短路 。

    假设任意路线走回 2 点的话费是 K0  , 那么必定存在一种 K0+ t 花费(在min(d1,2, d2,3) 来回跑一次)的方案, 那么就是用最短路解不等式了,有点线性规划的感觉。

    /*hdu6071[最短路+同余优化] 2017多校4*/
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef pair<LL, int> P;
    int G[5][5];
    int T, n, a, b, c, d;
    LL cnt = 0;
    LL t, k, dis[5][60005];
    void init() {
        memset(dis, 0x3f, sizeof(dis));
        memset(G, 0, sizeof(G));
    } priority_queue<P, vector<P>, greater<P> >pq;
    void dij(int u) {
        while (!pq.empty()) pq.pop();
        pq.push(P(0LL, u));
        while (!pq.empty()) {
            LL w = pq.top().first;
            int v = pq.top().second;
            pq.pop();
            if (w > dis[v][w % t]) continue;
            for (int i = -1; i < 3; i += 2) {
                int nxtp = (((v + i) % 4) == 0 ? 4 : (v + i) % 4);
                LL nxtw = w + G[v][nxtp] ;
                if (dis[nxtp][nxtw % t] > nxtw) {
                    dis[nxtp][nxtw % t] = nxtw;
                    //cnt++;
                    pq.push(P(nxtw, nxtp));
                }
            }
        }
    }
    void solve() {
        init();
        LL ans = 0x3f3f3f3f3f3f3f3f;
        scanf("%lld%d%d%d%d", &k, &a, &b, &c, &d);
        G[1][2] = G[2][1] = a;
        G[2][3] = G[3][2] = b;
        G[3][4] = G[4][3] = c;
        G[4][1] = G[1][4] = d;
        t = 2 * min(G[2][1], G[2][3]);
        //printf("%.2f
    ", (double)clock() / CLOCKS_PER_SEC );
        dij(2);
        //cout << cnt << endl,cnt=0;
        //printf("%.2f
    ", (double)clock() / CLOCKS_PER_SEC );
        for (int i = 0; i < t; i++) {
            if (k <= dis[2][i]) {
                ans = min(dis[2][i], ans);
            }
            else {
                ans = min(ans, dis[2][i] + ((k - dis[2][i] + t - 1) / t) * t);
            }
        }
        printf("%lld
    ", ans);
    }
    int main() {
        scanf("%d", &T);
        while (T--) solve();
        return 0;
    }
     
  • 相关阅读:
    正则表达式
    理解CPU steal time
    装饰器(带参数)
    装饰器(入门)
    递归
    冒泡算法
    Chrome for Mac键盘快捷键!来自Google Chrome官网!
    swoole深入学习 4. process
    通俗讲解 异步,非阻塞和 IO 复用
    swoole深入学习 3. upd Server和udp Client
  • 原文地址:https://www.cnblogs.com/UnderSilenceee/p/7288143.html
Copyright © 2011-2022 走看看