zoukankan      html  css  js  c++  java
  • Codeforces 786B Legacy (线段树优化建图)

    Codeforces 786B Legacy (线段树优化建图)


    题意:(n)个点,有(3)种连边操作:1.将(u)指向(v);2.将(v)指向编号在区间([l,r])的点;3.将([l,r])中的所有点指向(v)

    做法:线段树优化建图。拓展一些新的节点来代表某些区间的点,然后,如果需要进行区间([L,R])连边,那么就可以将([L,R])拆成一些区间的组合,以此减少边的数目。于是可以利用线段树,将每个线段树上的节点新建出来,连接对应的区间即可,而因为如果只有一颗线段树不能对所有点跑最短路,所以我们建两棵线段树,一颗指向序列,另一颗从序列指出来。原本对应的区间边权设为0,跑最短路即可。

    #include <cstdio>
    #include <algorithm>
    #include <iostream>
    #include <vector>
    #include <queue>
    #include <cstring>
    #define IOS ios::sync_with_stdio(false)
    #define pb push_back
    #define Pii pair<int,int>
    #define Ppi pair<Pii, int>
    #define x first
    #define y second
    typedef long long ll;
    const int N = 100020;
    inline void read(int &x) {
        x = 0; int f = 1; char c = getchar();
        while(!isdigit(c)) {if(c=='-')f=-1;c=getchar();}
        while(isdigit(c)) {x=x*10+c-'0';c=getchar();}
        x *= f;
    }
    using namespace std;
    bool ST;
    int n, q, st;
    struct edge {int e,w,nxt;} E[10000003];
    int h[6000000], cc;
    void add(int u, int v, int w) {
        E[cc].e = v; E[cc].w = w; E[cc].nxt = h[u]; h[u] = cc; ++cc;
    }
    int ID[2][N << 2], id;
    void build(int p, int l, int r, int typ) {
        ID[typ][p] = ++id;
        if(!typ) for(int i = l; i <= r; ++i) add(ID[typ][p], i, 0);
        else for(int i = l; i <= r; ++i) add(i, ID[typ][p], 0);
        if(l == r) return;
        int mid = (l + r) >> 1;
        build(p<<1,l,mid,typ);
        build(p<<1|1,mid+1,r,typ);
    }
    void update(int p, int l, int r, int v, int L,int R, int w, int typ) {
        if(l == L && r == R) {
            if(!typ) add(v, ID[typ][p], w);
            else add(ID[typ][p], v, w);
            return;
        }
        int mid = (l + r) >> 1;
        if(R <= mid) update(p<<1,l,mid, v,L,R,w,typ);
        else if(L > mid) update(p<<1|1,mid+1,r, v,L,R,w,typ);
        else {
            update(p<<1,l,mid, v,L,mid,w,typ);
            update(p<<1|1,mid+1,r, v,mid+1,R,w,typ);
        }
    }
    struct node {
        int e; ll w;
        node(){}
        node(int a, ll b) {e=a;w=b;}
        bool operator < (const node &a) const {
            return w > a.w;
        }
    };
    ll dis[6000001];
    int vis[6000001];
    void dij(int st) {
        for(int i = 1; i <= id; ++i) dis[i] = __LONG_LONG_MAX__;
        priority_queue< node > q;
        q.push(node(st,0)); dis[st] = 0;
        while(!q.empty()) {
            node u = q.top(); q.pop();
            if(vis[u.e]) continue;
            vis[u.e] = 1;
            for(int i = h[u.e]; ~i ; i = E[i].nxt) {
                int v = E[i].e; ll w = E[i].w;
                if(dis[u.e] != __LONG_LONG_MAX__ && dis[v] > dis[u.e] + w) {
                    dis[v] = dis[u.e] + w;
                    q.push(node(v,dis[v]));
                }
            }
        }
    }
    int main() {
        read(n), read(q), read(st);
        memset(h, -1, sizeof(h));
        id = n;
        build(1,1,n,0); // tree -> []
        build(1,1,n,1); // [] -> tree
        for(int opt,u,v,w,l,r,i = 1; i <= q; ++i) {
            read(opt);
            if(opt == 1) read(u), read(v), read(w), add(u, v, w);
            else if(opt == 2) read(v), read(l), read(r), read(w), update(1,1,n, v,l,r,w, 0);
            else read(v), read(l), read(r), read(w), update(1,1,n, v,l,r,w, 1);
        }
        dij(st);
        for(int i = 1; i <= n; ++i) printf("%lld ",dis[i] == __LONG_LONG_MAX__ ? -1 : dis[i]); puts("");
    }
    
  • 相关阅读:
    各国语言缩写列表,各国语言缩写-各国语言简称,世界各国域名缩写
    How to see log files in MySQL?
    git 设置和取消代理
    使用本地下载和管理的免费 Windows 10 虚拟机测试 IE11 和旧版 Microsoft Edge
    在Microsoft SQL SERVER Management Studio下如何完整输出NVARCHAR(MAX)字段或变量的内容
    windows 10 x64系统下在vmware workstation pro 15安装macOS 10.15 Catelina, 并设置分辨率为3840x2160
    在Windows 10系统下将Git项目签出到磁盘分区根目录的方法
    群晖NAS(Synology NAS)环境下安装GitLab, 并在Windows 10环境下使用Git
    使用V-2ray和V-2rayN搭建本地代理服务器供局域网用户连接
    windows 10 专业版安装VMware虚拟机碰到的坑
  • 原文地址:https://www.cnblogs.com/RRRR-wys/p/10333247.html
Copyright © 2011-2022 走看看