首页 > 其他 > 详细

G. 神圣的 F2 连接着我们 线段树优化建图+最短路

时间:2019-08-20 21:12:45      阅读:88      评论:0      收藏:0      [点我收藏+]

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

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\n", 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\n", 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\n", u, e.to, e.dist);
            // printf("d[%d]=%lld d[%d]=%lld\n", u, d[u], e.to, d[e.to]);
            if (d[e.to] > d[u] + e.dist) {
                // printf("ww\n");
                d[e.to] = d[u] + e.dist;
                // printf("d[%d]=%lld\n", e.to, d[e.to]);
                que.push(heapnode(d[e.to], e.to));
            }
        }
        // printf("\n");
    }
}

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\n");
    else printf("%lld\n", ans);
    return 0;
}
View Code

 

 

技术分享图片

 

G. 神圣的 F2 连接着我们 线段树优化建图+最短路

原文:https://www.cnblogs.com/EchoZQN/p/11385589.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!