ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF786B Legacy 线段树优化建图

2019-10-16 19:52:20  阅读:306  来源: 互联网

标签:int 线段 inq st 建图 Legacy CF786B dis


CF786B Legacy

### 线段树优化建图

Luogu链接
裸题,区间连点,点连区间
假如直接连边跑的话一定会T
这时候就需要线段树优化建图了
两个线段树
一个树是区间连点的,叫out
一个树是点连区间的,叫in
但是两个树内部连边的方向不一样
如图

假如相反必然就不对了包含关系错了
剩下的就好写了


代码如下:

#include<bits/stdc++.h>
#define mk make_pair
#define int long long
using namespace std;
const int maxn=1e5+10,inf=0x3f3f3f3f3f3f3f3f;
int n,q,st,cnt,trin[maxn<<2],trot[maxn<<2];
vector<pair<int,int> > G[maxn*10];
void build(int p,int l,int r){
    if(l==r){
        trin[p]=l;trot[p]=r;return;
    }
    int mid=(l+r)>>1;
    build(p<<1,l,mid);build(p<<1|1,mid+1,r);
    trin[p]=++cnt;trot[p]=++cnt;
    G[trot[p<<1]].push_back(mk(trot[p],0));
    G[trot[p<<1|1]].push_back(mk(trot[p],0));
    G[trin[p]].push_back(mk(trin[p<<1],0));
    G[trin[p]].push_back(mk(trin[p<<1|1],0));
}
void upin(int p,int l,int r,int x,int y,int from,int cs){
    if(x<=l && r<=y){
        G[from].push_back(mk(trin[p],cs));return;
    }
    int mid=(l+r)>>1;
    if(x<=mid) upin(p<<1,l,mid,x,y,from,cs);
    if(y>mid) upin(p<<1|1,mid+1,r,x,y,from,cs);
}
void upot(int p,int l,int r,int x,int y,int to,int cs){
    if(x<=l && r<=y){
        G[trot[p]].push_back(mk(to,cs));return;
    }
    int mid=(l+r)>>1;
    if(x<=mid) upot(p<<1,l,mid,x,y,to,cs);
    if(y>mid) upot(p<<1|1,mid+1,r,x,y,to,cs);
}
int dis[maxn*10],inq[maxn*10];
inline void spfa(){
    memset(dis,0x3f,sizeof(dis));memset(inq,0,sizeof(inq));
    queue<int> q;q.push(st);dis[st]=0;inq[st]=1;
    while(q.size()){
        int x=q.front();q.pop();inq[x]=0;
        for(unsigned int i=0;i<G[x].size();i++){
            int y=G[x][i].first,z=G[x][i].second;
            if(dis[y]>dis[x]+z){
                dis[y]=dis[x]+z;
                if(!inq[y]){
                    inq[y]=1;q.push(y);
                }
            }
        }
    }
}
signed main()
{
    scanf("%lld%lld%lld",&n,&q,&st);
    cnt=n;
    build(1,1,n);
    for(int op,i=1;i<=q;i++){
        scanf("%d",&op);
        if(op==1){
            int f,t,w;scanf("%lld%lld%lld",&f,&t,&w);G[f].push_back(mk(t,w));
        }
        if(op==2){
            int f,l,r,w;scanf("%lld%lld%lld%lld",&f,&l,&r,&w);
            upin(1,1,n,l,r,f,w);
        }
        if(op==3){
            int t,l,r,w;scanf("%lld%lld%lld%lld",&t,&l,&r,&w);
            upot(1,1,n,l,r,t,w);
        }
    }
    spfa();
    for(int i=1;i<=n;i++){
        if(dis[i]<inf) printf("%lld ",dis[i]);
        else printf("-1 ");
    }
    return 0;
}

标签:int,线段,inq,st,建图,Legacy,CF786B,dis
来源: https://www.cnblogs.com/ChrisKKK/p/11687988.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有