zoukankan      html  css  js  c++  java
  • CodeForces 787D--Legacy(最短路线段树优化建图)

    题目链接:https://codeforces.com/contest/787/problem/D

    题目大意:有n个星球,你有q个单向传送门

    类型1,$u$  $v$  $w$,表示从$u$到$v$花费$w$

    类型2,$u$  $l$   $r$  $w$,表示从$u$到区间$[l,r]$中的任意的星球,花费$w$

    类型3,$u$  $l$   $r$  $w$,表示从$[l,r]$中任意的星球到$u$,花费$w$,

    问从s开始到每个星球的最短距离,如果无法到达则输出-1

    Examples

    Input
    3 5 1
    2 3 2 3 17
    2 3 2 2 16
    2 2 2 3 3
    3 3 1 1 12
    1 3 3 17
    Output
    0 28 12 
    Input
    4 3 1
    3 4 1 3 12
    2 2 3 4 10
    1 2 4 16
    Output
    0 -1 -1 12 

    emmm,之前已经写过了一篇了,现在在做又WA了好几发QAQ。。。以下是以前写的博客,里面有详细的解说

    https://blog.csdn.net/qq_43906000/article/details/102256830

    主要就是用两颗线段树来对区间建立路径做个优化

    贴一下代码吧QAQ

    以下是AC代码:

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    using namespace std;
    
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    #define lc rt<<1
    #define rc rt<<1|1
    typedef long long ll;
    const int mac=1e5+10;
    const ll inf=1e18+10;
    
    struct node
    {
        int id;
        ll s;
        bool operator<(const node &a)const {
            return s>a.s;
        }
    };
    struct Edge
    {
        int to,next,w;
    }eg[mac*20];
    ll dis[mac*10];
    int head[mac*10],tree1[mac<<2],tree2[mac<<2];
    int idx,pa[mac],pb[mac],num;
    bool vis[mac*10];
    
    void add(int u,int v,int w)
    {
        eg[num]=Edge{v,head[u],w};
        head[u]=num++;
    }
    
    void build1(int l,int r,int rt)
    {
        tree1[rt]=++idx;
        if (l==r){
            pa[l]=tree1[rt];
            return;
        }
        int mid=(l+r)>>1;
        build1(lson);build1(rson);
        add(tree1[rt],tree1[lc],0);
        add(tree1[rt],tree1[rc],0);
    }
    
    void build2(int l,int r,int rt)
    {
        tree2[rt]=++idx;
        if (l==r){
            pb[l]=tree2[rt];
            add(pa[l],tree2[rt],0);
            return;
        }
        int mid=(l+r)>>1;
        build2(lson);build2(rson);
        add(tree2[lc],tree2[rt],0);
        add(tree2[rc],tree2[rt],0);
    }
    
    void update_to_range(int l,int r,int rt,int st,int L,int R,int w)
    {
        if (l>=L && r<=R){
            add(pb[st],tree1[rt],w);
            return;
        }
        int mid=(l+r)>>1;
        if (mid>=L) update_to_range(lson,st,L,R,w);
        if (mid<R) update_to_range(rson,st,L,R,w);
    }
    
    void update_to_pos(int l,int r,int rt,int L,int R,int ed,int w)
    {
        if (l>=L && r<=R){
            add(tree2[rt],pa[ed],w);
            return;
        }
        int mid=(l+r)>>1;
        if (mid>=L) update_to_pos(lson,L,R,ed,w);
        if (mid<R) update_to_pos(rson,L,R,ed,w);
    }
    
    void dij(int st)
    {
        priority_queue<node>q;
        q.push(node{st,0});
        dis[st]=0;
        while (!q.empty()){
            node now=q.top();
            q.pop();
            int u=now.id;
            if (vis[u]) continue;
            vis[u]=true;
            for (int i=head[u]; i!=-1; i=eg[i].next){
                int v=eg[i].to;
                if (vis[v]) continue;
                if (dis[v]>dis[u]+1LL*eg[i].w){
                    dis[v]=dis[u]+1LL*eg[i].w;
                    q.push(node{v,dis[v]});
                }
            }
        }
    }
    
    int main(int argc, char const *argv[])
    {
        //freopen("in.txt","r",stdin);
        int n,q,s;
        scanf ("%d%d%d",&n,&q,&s);
        memset(head,-1,sizeof head);
        build1(1,n,1); build2(1,n,1);
        for (int i=1; i<=q; i++){
            int id,u,v,w,l,r;
            scanf ("%d",&id);
            if (id==1) {
                scanf ("%d%d%d",&u,&v,&w);
                add(pb[u],pa[v],w);
            }
            else{
                scanf ("%d%d%d%d",&v,&l,&r,&w);
                if (id==2) update_to_range(1,n,1,v,l,r,w);
                else update_to_pos(1,n,1,l,r,v,w);
            }
        }
        for (int i=1; i<n*10; i++) dis[i]=inf;
        dij(pb[s]);
        for (int i=1; i<=n; i++){
            if (dis[pb[i]]==inf) printf("%d%c",-1,i==n?'
    ':' ');
            else printf("%lld%c",dis[pb[i]],i==n?'
    ':' ');
        }
        return 0;
    }
    路漫漫兮
  • 相关阅读:
    深入浅出Mybatis系列(八)---objectFactory、plugins、mappers
    深入浅出Mybatis系列(七)---TypeHandler简介
    深入浅出Mybatis系列(六)---配置详解之typeAliases别名
    深入浅出Mybatis系列(四)---配置详解之properties与environments
    fastjson 的使用总结
    Java 中 Gson的使用
    Lombok介绍、使用方法和总结
    Jackson的使用和定制
    深入浅出Mybatis系列(三)---配置简介(mybatis源码篇)
    深入浅出Mybatis系列(二)---Mybatis入门
  • 原文地址:https://www.cnblogs.com/lonely-wind-/p/13281124.html
Copyright © 2011-2022 走看看