• CF786B/CF787D Legacy


    题目描述:

    luogu

    cf

    cf

    题解:

    最短路+线段树优化建图。

    考虑本题的边是点->点、段->点和点->段,我们可以建线段树然后拆成入点和出点。

    入点:儿子->父亲,边权为0;

    出点:父亲->儿子,边权为0;

    叶子:出点->入点,边权为0;

    那么连续的一段可以用不超过$log;n$个节点表示,最后跑最短路即可。

    代码:

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int N = 100050;
    const ll  Inf = 0x3f3f3f3f3f3f3f3fll;
    template<typename T>
    inline void read(T&x)
    {
        T f = 1,c = 0;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
        x = f*c;
    }
    int n,Q,S,hed[N*10],cnt,tot;
    ll dis[N*10];
    bool vis[N*10];
    struct EG
    {
        int to,nxt;
        ll w;
    }e[30*N];
    void ae(int f,int t,ll w)
    {
        e[++cnt].to = t;
        e[cnt].nxt = hed[f];
        e[cnt].w = w;
        hed[f] = cnt;
    }
    int sta[N],tl;
    struct segtree
    {
        int s[N<<2][2];
        void build(int l,int r,int u)
        {
            s[u][0]=++tot,s[u][1]=++tot;
            if(l==r){ae(s[u][1],s[u][0],0);return ;}
            int mid = (l+r)>>1;
            build(l,mid,u<<1),build(mid+1,r,u<<1|1);
            ae(s[u<<1][0],s[u][0],0),ae(s[u<<1|1][0],s[u][0],0);
            ae(s[u][1],s[u<<1][1],0),ae(s[u][1],s[u<<1|1][1],0);
        }
        int query(int l,int r,int u,int qx,int k)
        {
            if(l==r)return s[u][k];
            int mid = (l+r)>>1;
            if(qx<=mid)return query(l,mid,u<<1,qx,k);
            else return query(mid+1,r,u<<1|1,qx,k);
        }
        void query(int l,int r,int u,int ql,int qr,int k)
        {
            if(l==ql&&r==qr){sta[++tl]=s[u][k];return ;}
            int mid = (l+r)>>1;
            if(qr<=mid)query(l,mid,u<<1,ql,qr,k);
            else if(ql>mid)query(mid+1,r,u<<1|1,ql,qr,k);
            else query(l,mid,u<<1,ql,mid,k),query(mid+1,r,u<<1|1,mid+1,qr,k);
        }
        void print(int l,int r,int u)
        {
            if(l==r){if(dis[s[u][0]]==Inf)printf("-1 ");else printf("%lld ",dis[s[u][0]]);return ;}
            int mid = (l+r)>>1;
            print(l,mid,u<<1);print(mid+1,r,u<<1|1);
        }
    }tr;
    struct Pair
    {
        int x;ll y;
        Pair(){}
        Pair(int x,ll y):x(x),y(y){}
        bool operator < (const Pair&a)const{return y>a.y;}
    };
    priority_queue<Pair>q;
    void dij()
    {
        memset(dis,0x3f,sizeof(dis));
        S = tr.query(1,n,1,S,0);
        dis[S]=0;q.push(Pair(S,0));
        while(!q.empty())
        {
            Pair tp = q.top();q.pop();
            int u = tp.x;if(vis[u])continue;vis[u] = 1;
            for(int j=hed[u];j;j=e[j].nxt)
            {
                int to = e[j].to;
                if(dis[to]>dis[u]+e[j].w)
                {
                    dis[to] = dis[u]+e[j].w;
                    q.push(Pair(to,dis[to]));
                }
            }
        }
    }
    int main()
    {
    //    freopen("tt.in","r",stdin);
        read(n),read(Q),read(S);
        tr.build(1,n,1);
        for(int op,a,b,c,d,i=1;i<=Q;i++)
        {
            read(op),read(a),read(b),read(c);
            if(op==1)
            {
                a = tr.query(1,n,1,a,0),b = tr.query(1,n,1,b,1);
                ae(a,b,c);
            }else
            {
                read(d);
                if(op==2)
                {
                    int f = tr.query(1,n,1,a,0);
                    tl = 0;tr.query(1,n,1,b,c,1);
                    for(int j=1;j<=tl;j++)
                        ae(f,sta[j],d);
                }else
                {
                    tl = 0;tr.query(1,n,1,b,c,0);
                    int t = tr.query(1,n,1,a,1);
                    for(int j=1;j<=tl;j++)
                        ae(sta[j],t,d);
                }
            }
        }
        dij();
        tr.print(1,n,1);
        puts("");
        return 0;
    }
    View Code
  • 相关阅读:
    Golang学习开篇——Go语言优势
    Ubuntu —— 查看和开放端口
    mysql——sql语句
    python模块——xlwt
    字典容器类型使用之坑
    pandas——将sql查询结果,分几部分存入excel
    pandas 点击 excel 表格数据,跳转到 sheet2
    datetime——计算前一天的这个时间 坑
    报错总结
    nginx——部署前端
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/11130790.html
Copyright © 2020-2023  润新知