zoukankan      html  css  js  c++  java
  • G. 神圣的 F2 连接着我们 线段树优化建图+最短路

    这个题目和之前写的一个线段树优化建图是一样的。

    B - Legacy CodeForces - 787D 线段树优化建图+dij最短路 基本套路

    之前这个题目可以相当于一个模板,直接套用就可以了。

    不过注意为了提高效率,在区间与区间之间建边的时候建了两个虚点。

    题目 G. 神圣的 F2 连接着我们

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <queue>
    #include <vector>
    #include <string>
    #include <algorithm>
    #include <iostream>
    #include <map>
    #define inf 0x3f3f3f3f
    #define inf64 0x3f3f3f3f3f3f3f3f
    using namespace std;
    typedef long long ll;
    const int maxn = 2e5 + 10;
    int numa[maxn * 4], numb[maxn * 4], lefta[maxn * 4], leftb[maxn * 4];
    int start[maxn], endss[maxn];
    ll d[maxn * 8], tot;
    int n, m, p, q;
    bool vis[maxn * 8];
    struct edge {
        int from, to, dist;
        edge(int from = 0, int to = 0, int dist = 0) :from(from), to(to), dist(dist) {}
    };
    struct heapnode {
        ll d;
        int u;
        heapnode(ll d = 0, int u = 0) : d(d), u(u) {}
        bool operator<(const heapnode &a) const {
            return a.d < d;
        }
    };
    
    vector<edge> vec;
    vector<int> g[maxn * 8];
    
    void add(int u, int v, int w) {
        vec.push_back(edge(u, v, w));
        int m = vec.size();
        g[u].push_back(m - 1);
        // printf("u=%d v=%d w=%d
    ", u, v, w);
    }
    
    void dijkstra() {
        priority_queue<heapnode>que;
        for (int i = 0; i <= tot; i++) d[i] = inf64;
        for(int i=1;i<=q;i++)
        {
            int id = lefta[start[i] + n];
            d[id] = 0;
            que.push(heapnode(0, id));
        }
        memset(vis, 0, sizeof(vis));
        while (!que.empty()) {
            heapnode x = que.top(); que.pop();
            int u = x.u;
            // printf("u=%d
    ", u);
            if (vis[u]) continue;
            vis[u] = 1;
            for (int i = 0; i < g[u].size(); i++) {
                edge &e = vec[g[u][i]];
                // printf("u=%d e.to=%d e.dist=%d
    ", u, e.to, e.dist);
                // printf("d[%d]=%lld d[%d]=%lld
    ", u, d[u], e.to, d[e.to]);
                if (d[e.to] > d[u] + e.dist) {
                    // printf("ww
    ");
                    d[e.to] = d[u] + e.dist;
                    // printf("d[%d]=%lld
    ", e.to, d[e.to]);
                    que.push(heapnode(d[e.to], e.to));
                }
            }
            // printf("
    ");
        }
    }
    
    void builda(int id, int l, int r) {
        numa[id] = ++tot;
        int mid = (l + r) >> 1;
        if (l == r) {
            lefta[l] = tot;
            return;
        }
        builda(id << 1, l, mid);
        builda(id << 1 | 1, mid + 1, r);
        add(numa[id << 1], numa[id], 0);
        add(numa[id << 1 | 1], numa[id], 0);
    }
    
    void buildb(int id, int l, int r) {
        numb[id] = ++tot;
        int mid = (l + r) >> 1;
        if (l == r) {
            leftb[l] = tot;
            return;
        }
        buildb(id << 1, l, mid);
        buildb(id << 1 | 1, mid + 1, r);
        add(numb[id], numb[id << 1], 0);
        add(numb[id], numb[id << 1 | 1], 0);
    }
    
    void build3(int n) {
        for (int i = 1; i <= n; i++) add(leftb[i], lefta[i], 0);
    }
    
    void update(int id, int l, int r, int x, int y, vector<int>&d) {
        if (x <= l && y >= r) {
            d.push_back(id);
            return;
        }
        int mid = (l + r) >> 1;
        if (x <= mid) update(id << 1, l, mid, x, y, d);
        if (y > mid) update(id << 1 | 1, mid + 1, r, x, y, d);
    }
    vector<int>a, b;
    int main()
    {
        scanf("%d%d%d%d", &n, &m, &p, &q);
        builda(1, 1, 2 * n), buildb(1, 1, 2 * n), build3(2 * n);
        tot++;
        for (int i = 1; i <= m; i++) {
            int x1, y1, x2, y2, w;
            scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &w);
            a.clear(), b.clear();
            update(1, 1, 2 * n, x1, y1, a);
            update(1, 1, 2 * n, x2 + n, y2 + n, b);
            int lena = a.size(), lenb = b.size();
            for(int j=0;j<lena;j++)
            {
                int id = numa[a[j]];
                add(id, tot, 0);
            }
            add(tot, tot + 1, w);
            for(int j=0;j<lenb;j++)
            {
                int id = numb[b[j]];
                add(tot + 1, id, 0);
            }
            tot += 2;
            for(int j=0;j<lenb;j++)
            {
                int id = numa[b[j]];
                add(id, tot, 0);
            }
            add(tot, tot + 1, w);
            for(int j=0;j<lena;j++)
            {
                int id = numb[a[j]];
                add(tot + 1, id, 0);
            }
            tot += 2;
        }
        for (int i = 1; i <= p; i++) scanf("%d", &endss[i]);
        for (int i = 1; i <= q; i++) scanf("%d", &start[i]);
        dijkstra();
        ll ans = 0;
        for(int i=1;i<=p;i++)
        {
            int id = lefta[endss[i]];
            ans = max(ans, d[id]);
        }
        if (ans >= inf64) printf("boring game
    ");
        else printf("%lld
    ", ans);
        return 0;
    }
    View Code

  • 相关阅读:
    asp.net大文件断点续传
    JS大文件上传解决方案
    B/S大文件上传解决方案
    B/S上传整个文件夹
    网页上传整个文件夹
    POJ 1068 Parencodings
    74LS85 比較器 【数字电路】
    二叉树的建立与先序,后序,中序输出
    Android 学习之 开源项目PullToRefresh的使用
    理解矩阵及谱聚类小记
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/11385589.html
Copyright © 2011-2022 走看看