zoukankan      html  css  js  c++  java
  • wzj52501_图图的旅行

    【问题描述】
    图图是一个很萌很萌很可爱的好孩纸。
    图图计划去 Bzeroth 的精灵王国去旅游, 精灵王国由 n 座城市组成, 第 i
    城市有 3 个属性 x[i]w[i]t[i]
    在精灵王国的城市之间穿行只能依靠传送阵, 第 i 座城市的传送阵可以将图
    图从城市 i 传送到距离城市 i 不超过 w[i]的任意一个城市, 并需要 t[i]的时间完
    成传送。 现在图图知道了每个城市的坐标 x[i], 想知道他从城市 s 到城市 t 的最
    小时间。
    这么难的问题图图当然不会做了, 他想让你帮帮他, 你能解决这个问题
    吗?
    【输入】
    第一行包含 3 个正整数 nst, 表示城市个数, 起点城市和终点城市。
    第二行包含 n 个整数 x[i], 表示第 i 座城市的坐标。
    第三行包含 n 个整数 w[i], 表示第 i 座城市的传送距离。
    第四行包含 n 个整数 t[i], 表示第 i 座城市的传送时间。
    【输出】
    请输出从城市 s 到城市 t 的最小时间, 保证至少存在一组合法解。
    【输入输出样例】

    trip.in trip.out
    7 3 7
    -1 0 1 2 3 5 10
    11 0 1 1 4 10 2
    3 1 1 1 2 4 5
    7

    【样例解释】
    路线为 3 → 4 → 5 → 1 → 7, 时间之和为 7
    【数据范围】
    对于 30%的数据, 1 ≤ n ≤ 2501, 所有的 t[i]均相等。
    对于 60%的数据, 1 ≤ n ≤ 2501
    对于 100%的数据, 1 ≤ n ≤ 1525010w[i]t[i]|x[i]|109, 保证 x[i]
    格递增。


    利用线段树结构优化建边

    建完就是最短路了

    二分确定一个点能到达的最左最右的点

    另外,此题码量稍大,数组大小玄学

    #include<iostream>
    #include<cstdio>
    
    #define ri register int
    #define u int
    
    namespace opt {
    
        inline u in() {
            u x(0),f(1);
            char s(getchar());
            while(s<'0'||s>'9') {
                if(s=='-') f=-1;
                s=getchar();
            }
            while(s>='0'&&s<='9') {
                x=(x<<1)+(x<<3)+s-'0';
                s=getchar();
            }
            return x*f;
        }
    
    }
    
    using opt::in;
    
    #define NN 152505
    #define MM (152405*4)
    #define XX (152405*4)
    
    #include<algorithm>
    #include<cstring>
    #include<queue>
    
    namespace dj_ {
    
        using std::queue;
    
        typedef std::pair<u,u> p;
    
        std::priority_queue<p,std::vector<p>,std::greater<p> > q;
    
        u h[XX],cnt;
        long long d[XX];
    
        struct node {
            u to,next,va;
        } a[MM<<2];
    
        inline void add(const u &x,const u &y,const u &v) {
            a[++cnt].to=y,a[cnt].next=h[x],a[cnt].va=v,h[x]=cnt;
        }
    
        void run(const u &x) {
            d[x]=0,q.push(p(0,x));
            while(!q.empty()) {
                u _x(q.top().second),_dic(q.top().first);
                q.pop();
                if(_dic>d[_x]) continue;
                for(ri i(h[_x]); i; i=a[i].next) {
                    u _y(a[i].to);
                    if(d[_y]>d[_x]+a[i].va) {
                        d[_y]=a[i].va+d[_x];
                        q.push(p(d[_y],_y));
                    }
                }
            }
        }
    
    }
    
    namespace xds {
    
        u to[NN];
    
        void build(const u &rt,const u &l,const u &r) {
            dj_::d[rt]=((long long)(1)<<60);
            if(l==r) {
                to[l]=rt;
                return;
            }
            u mid((l+r)>>1);
            dj_::add(rt,rt<<1,0);
            dj_::add(rt,rt<<1|1,0);
            build(rt<<1,l,mid);
            build(rt<<1|1,mid+1,r);
        }
    
        void add(const u &rt,const u &l,const u &r,const u &x,const u &y,const u &st,const u &va) {
            if(l>=x&&r<=y) {
                dj_::add(st,rt,va);
                return;
            }
            u mid((l+r)>>1);
            if(mid>=x) {
                add(rt<<1,l,mid,x,y,st,va);
            }
            if(y>=mid+1) {
                add(rt<<1|1,mid+1,r,x,y,st,va);
            }
        }
    
    }
    
    namespace mainstay {
    
        using xds::to;
    
        u N,S,T;
    
        struct node {
            u d,t,r;
        } a[NN];
    
        u erf(const u &l,const u &r,const u &x,const u &k) {
            u _l(l),_r(r),_re(-1);
            if(!k) {
                while(_l<=_r) {
                    u mid((_l+_r)>>1);
                    if(a[mid].d>=x) {
                        _re=mid,_r=mid-1;
                    } else _l=mid+1;
                }
            }
            else while(_l<=_r) {
                u mid((_l+_r)>>1);
                if(a[mid].d<=x) {
                    _re=mid,_l=mid+1;
                } else _r=mid-1;
            }
            return _re;
        }
    
        inline void solve() {
            N=in(),S=in(),T=in();
            for(ri i(1); i<=N; ++i) a[i].d=in();
            for(ri i(1); i<=N; ++i) a[i].r=in();
            for(ri i(1); i<=N; ++i) a[i].t=in();
            xds::build(1,1,N);
            for(ri i(1); i<=N; ++i) {
                u _l(erf(1,N,a[i].d-a[i].r,0));
                u _r(erf(1,N,a[i].d+a[i].r,1));
                xds::add(1,1,N,_l,_r,to[i],a[i].t);
            }
            dj_::run(to[S]),printf("%lld",dj_::d[to[T]]);
        }
    
    }
    
    int main() {
    
        //freopen("trip.in","r",stdin);
        //freopen("trip.out","w",stdout);
        mainstay::solve();
    
    }
  • 相关阅读:
    JS复制内容到剪切板
    mysql root密码的重设方法(转)
    php生成excel文件示例代码(转)
    php读取文件内容的三种方式(转)
    使用火蜘蛛采集器Firespider采集天猫商品数据并上传到微店
    Mac Android8.0源码编译笔记
    开源 高性能 高可用 可扩展
    开源 模式
    开源 算法 数据结构
    mdb
  • 原文地址:https://www.cnblogs.com/ling-zhi/p/11759761.html
Copyright © 2011-2022 走看看