zoukankan      html  css  js  c++  java
  • Gym102174G 神圣的 F2 连接着我们(线段树优化建图)

    本题因为设计到区间到区间的连边,因此使用线段树优化建图

    原理就是用out树和in树,一棵儿子向父亲连边,一棵父亲向儿子连边,然后叶子和叶子连边,对于两个区间的连边,用一个附加节点来表示连接。

    建树使用动态开点,但是本题的内存需要计算,不然就会出现开大mle,小则re的尴尬情况

    建完图后就是跑一下最短路即可。每个人的线段树优化建图都不相同,挑一个喜欢的模板即可,但是注意,有些模板题是只有点到区间或者区间到点,他们可能没有用附加节点。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=1e5+10;
    const int M=1e5+10;
    const ll inf=1e18;
    int cnt;
    int X[N],Y[N];
    struct node{
        int l,r;
        int id;
    }in[N<<2],out[N<<2];
    struct pd{
        int id;
        ll w;
        bool operator <(const pd &t) const{
            return w>t.w;
        }
    };
    int n,m,p,Q;
    int id1[18*N+2*M+2],id2[18*N+2*M+2];
    vector<pd> g[18*N+2*M+2];
    ll dis[18*N+2*M+2];
    bool vis[18*N+2*M+2];
    priority_queue<pd> q;
    void add(int u,int v,int w){
        g[u].push_back({v,w});
    }
    int build(int k,int l,int r,node tr[],int *a,int type){
        tr[k]={l,r,++cnt};
        if(l==r){
            a[l]=cnt;
            return tr[k].id;
        }
        int mid=l+r>>1;
        if(type){
            add(tr[k].id,build(k<<1,l,mid,tr,a,type),0);
            add(tr[k].id,build(k<<1|1,mid+1,r,tr,a,type),0);
        }
        else{
            add(build(k<<1,l,mid,tr,a,type),tr[k].id,0);
            add(build(k<<1|1,mid+1,r,tr,a,type),tr[k].id,0);
        }
        return tr[k].id;
    }
    void modify(int u,int l,int r,int now,node tr[],int w,int type){
        if(tr[u].l>=l&&tr[u].r<=r){
            if(type)
                add(now,tr[u].id,w);
            else
                add(tr[u].id,now,w);
            return ;
        }
        int mid=tr[u].l+tr[u].r>>1;
        if(l<=mid)
            modify(u<<1,l,r,now,tr,w,type);
        if(r>mid)
            modify(u<<1|1,l,r,now,tr,w,type);
    }
    void dij(){
        while(q.size()){
            auto t=q.top();
            q.pop();
            if(vis[t.id])
                continue;
            vis[t.id]=1;
            for(int i=0;i<(int)g[t.id].size();i++){
                int j=g[t.id][i].id;
                if(dis[j]>dis[t.id]+g[t.id][i].w){
                    dis[j]=dis[t.id]+g[t.id][i].w;
                    q.push({j,dis[j]});
                }
            }
        }
    }
    int main(){
        ios::sync_with_stdio(false);
        cin>>n>>m>>p>>Q;
        build(1,1,2*n,in,id1,0);
        build(1,1,2*n,out,id2,1);
        int i;
        for(i=1;i<=2*n;i++){
            add(id1[i],id2[i],0);
            add(id2[i],id1[i],0);
        }
        while(m--){
            int a,b,c,d,w;
            cin>>a>>b>>c>>d>>w;
            c+=n,d+=n;
            modify(1,a,b,++cnt,in,w,0);
            modify(1,c,d,cnt,out,0,1);
            modify(1,c,d,++cnt,in,w,0);
            modify(1,a,b,cnt,out,0,1);
        }
        for(i=1;i<=p;i++)
            cin>>X[i];
        for(i=1;i<=Q;i++){
            cin>>Y[i];
            Y[i]+=n;
        }
        for(i=1;i<=cnt;i++){
            dis[i]=1e18;
        }
        for(i=1;i<=Q;i++){
            dis[id1[Y[i]]]=0;
            q.push({id1[Y[i]],0});
        }
        dij();
        ll ans=0;
        for(i=1;i<=p;i++){
            ans=max(ans,dis[id2[X[i]]]);
        }
        if(ans==inf){
            cout<<"boring game"<<endl;
        }
        else{
            cout<<ans<<endl;
        }
    }
    View Code
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    关于css兼容性问题及一些常见问题汇总
    CSS3使用transition属性实现过渡效果
    CSS3 画基本图形,圆形、椭圆形、三角形等
    总结30个CSS3选择器
    javascript中call()、apply()的区别
    JavaScript面试技巧之数组的一些不low操作
    详解bootstrap-fileinput文件上传控件的亲身实践
    js控制随机数生成概率代码实例
    jQuery 第十章 工具方法-高级方法 $.ajax() $.Callbacks() .....
    jQuery 第九章 工具方法之插件扩展 $.extend() 和 $.fn.extend()
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/13996121.html
Copyright © 2011-2022 走看看