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();
    
    }
  • 相关阅读:
    cf1100 F. Ivan and Burgers
    cf 1033 D. Divisors
    LeetCode 17. 电话号码的字母组合
    LeetCode 491. 递增的子序列
    LeetCode 459.重复的子字符串
    LeetCode 504. 七进制数
    LeetCode 3.无重复字符的最长子串
    LeetCode 16.06. 最小差
    LeetCode 77. 组合
    LeetCode 611. 有效三角形个数
  • 原文地址:https://www.cnblogs.com/ling-zhi/p/11759761.html
Copyright © 2011-2022 走看看