• AT4845 [ABC164E] Two Currencies


    原题链接

    • 题意:有 (n) 个城市,它们由 (m) 条双向道路连接,保证它们能够彼此到达。第 (i) 条道路连接 (u_i,v_i) ,需要花费 (x_i) 个银币,耗费 (t_i) 秒的时间。每个城市处都有兑换银币处,第 (i) 个城市中你可以用 (1) 个金币兑换 (c_i) 个银币,可以兑换无限次,不过兑换 (1) 次需要花费 (d_i) 秒的时间。你一开始在 (1) 号城市,有 (s) 个银币和无限多的金币,求到其它城市需要耗费的最小时间。(1<=n<=50)(1<=x_i <=50)(1 <= t_i, c_i, s, d_i <= 10^9)
    • 题解:很明显建分层图,然后跑 (dij) ,显然的是,因为 (x_i) 设定过于小,所以,分层图点的数量是 (n^3) ,需要注意的是,初期接触分层图,这个是表示了两个状态,是点和在当前点一共有的钱,这两个状态要搞成一维的才方便,但是一开始是设定的是 (x imes 2500 + money + 1) 发现有重合,所以当搞到 (x imes 5000 + money + 1) 才不会重合,这个处理不能太草率。
    • 代码:
    #include <algorithm>
    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <map>
    #include <queue>
    #include <stack>
    #include <vector>
    using namespace std;
    typedef long long ll;
    const ll N = 1e6 + 99;
    const ll NN = 2500;
    ll pos(ll x, ll money) {
        return x*2 * 2500 + money + 1;
    }
    struct edge {
        ll v, w;
    };
    vector<edge>G[N];
    struct Node {
        ll pos, dis;
        bool operator<(Node rhs)const {
            return rhs.dis < dis;
        }
    };
    priority_queue<Node>pq;
    bool vis[N];
    ll d[N];
    void dij(ll s) {
        pq.push({s, 0});
        memset(d, 0x3f, sizeof d);
        d[s] = 0;
        while (!pq.empty()) {
            auto now = pq.top();
            pq.pop();
            ll u = now.pos;
            if (vis[u])continue;
            vis[u] = 1;
            for (auto e:G[u]) {
                if (d[e.v] > d[u] + e.w) {
                    d[e.v] = d[u] + e.w;
                    pq.push({e.v, d[e.v]});
                }
            }
        }
    }
    void add(ll u, ll v, ll w) {G[u].push_back({v, w});}
    ll co[N], dd[N];
    void solve() {
        ll n, m, kk;
        cin >> n >> m >> kk;
        for (ll i = 1; i <= m; i++) {
            ll u, v, c, t;
            cin >> u >> v >>c >> t;
            for (ll j = c; j <= NN; j++ ) {
                add(pos(u, j), pos(v, j - c), t);
                add(pos(v, j), pos(u, j - c), t);
            }
        }
        for (ll i = 1; i <= n; i++) {
            cin >> co[i] >> dd[i];
            for (ll j = 0; j + co[i] <= NN; j++) {
                add(pos(i, j), pos(i, j + co[i]), dd[i]);
            }
        }
        dij(pos(1, min(NN, kk)));
        for (ll i = 2; i <= n; i++) {
            ll ans = d[pos(i, 0)];
            for (ll j = 0; j <= NN; j++) {
                ans = min(d[pos(i, j)], ans);
            }
            cout << ans << endl;
        }
    }
    signed main() {
        ll t = 1;
        while (t--) solve();
        return 0;
    }
    
  • 相关阅读:
    Operation Queue
    Dispatch Sources
    Base64编码详解
    属性存取、直接访问实例变量
    管理关联对象和NSDictionary区别
    3个Block替换Delegate的场景
    Objective-C消息机制
    Dispatch Queues调度队列
    DNS64/NAT64 Networks(解决IPv6审核被拒)
    NSObject的Initialize与Load方法
  • 原文地址:https://www.cnblogs.com/Xiao-yan/p/14581002.html
Copyright © 2020-2023  润新知