• HDU 5361 In Touch (2015 多校6 1009 最短路 + 区间更新)


    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5361

    题意:最短路。求源点到全部点的最短距离。但与普通最短路不同的是,给出的边是某点到区间[l,r]内随意点的距离。
    输入一个n,代表n个点,输入n个l[i],输入n个r[i],输入n个c[i]。
    对于i,表示i到区间[i - r[i]],i - l[i]]和区间[i + l[i],i + r[i]]内的随意点的距离为c[i]。


    求1到各个点的最短距离。

    思路:若建边跑最短路的话,由于边过多,所以不可行。

    由于在最后的结果中。可能源点1到某段区间的最短路径都是一样的,所以能够在最短路的算法基础上利用线段树区间更新来维护源点1到区间的最短路径,最后仅仅须要查询区间就可以。线段树的每一个结点存该区间源点到该区间点的最短路的最大值和最小值。

    所以叶子结点即是源点1到该点的最短路径。(思路来源队友)

    代码:

    #include <iostream>
    #include <iomanip>
    #include <stdio.h>
    #include <string>
    #include <string.h>
    #include <math.h>
    #include <queue>
    #include <set>
    #include <vector>
    #include <algorithm>
    
    using namespace std;
    
    #define lson l, m, rt << 1
    #define rson m + 1, r, rt << 1 | 1
    
    const long long INF = 1e18;
    const int N = 2e5 + 10;
    
    struct Segment {
        int l, r;
        long long d;
    
        Segment(int l = 0, int r = 0, long long d = 0) {
            this -> l = l;
            this -> r = r;
            this -> d = d;
        }
    
        friend bool operator < (Segment a, Segment b) {
            return a.d > b.d;
        }
    };
    
    struct Node {
        int used;//标记该段区间是否使用过。由于距离均为正值,所以若该区间已是最短距离,则不须要继续更新。
        long long _max;
        long long _min;
    };
    
    Node node[N << 2];
    long long lazy[N << 2];
    int n;
    int lef[N];
    int rig[N];
    long long c[N];
    priority_queue<Segment> q;
    
    void pushup(int rt) {
        node[rt]._max = max(node[rt << 1]._max, node[rt << 1 | 1]._max);
        node[rt]._min = min(node[rt << 1]._min, node[rt << 1 | 1]._min);
        if (node[rt << 1].used == node[rt << 1 | 1].used)
            node[rt].used = node[rt << 1].used;
        else
            node[rt].used = -1;
    }
    
    void pushdown(int rt) {
        if (lazy[rt] != -1) {
            lazy[rt << 1] = lazy[rt << 1 | 1] = lazy[rt];
            node[rt << 1]._min = node[rt << 1]._max = lazy[rt];
            node[rt << 1 | 1]._min = node[rt << 1 | 1]._max = lazy[rt];
            lazy[rt] = -1;
        }
    }
    
    void build(int l, int r, int rt) {
        node[rt]._max = INF;
        node[rt]._min = INF;
        node[rt].used = 0;
        lazy[rt] = -1;
        if (l == r) {
            if (l == 1) {
                node[rt]._max = 0;
                node[rt]._min = 0;
            }
            return ;
        }
        int m = (l + r) >> 1;
        build(lson);
        build(rson);
        pushup(rt);
    }
    
    void update(long long cr, int L, int R, int l, int r, int rt) {
        if (node[rt]._max <= cr)
            return ;
        if (L <= l && r <= R) {
            node[rt]._max = cr;
            if (node[rt]._min > cr) {
                node[rt]._min = cr;
                q.push(Segment(l, r, cr));
                lazy[rt] = cr;
                return ;
            }
        }
        if (l == r)
            return ;
        pushdown(rt);
        int m = (l + r) >> 1;
        if (L <= m)
            update(cr, L, R, lson);
        if (R > m)
            update(cr, L, R, rson);
        pushup(rt);
    }
    
    void querysegment(Segment ff, int l, int r, int rt) {
        if (node[rt].used == 1)
            return ;
        if (ff.l <= l && r <= ff.r) {
            if (node[rt].used == 0) {
                for (int i = l; i <= r; i++) {
                    int le = i + lef[i];
                    int ri = min(n, i + rig[i]);
                    if (le <= n) {
                        update(ff.d + c[i], le, ri, 1, n, 1);
                    }
                    le = max(1, i - rig[i]);
                    ri = i - lef[i];
                    if (ri >= 1) {
                        update(ff.d + c[i], le, ri, 1, n, 1);
                    }
                }
                node[rt].used = 1;
                return ;
            }
        }
        if (l == r)
            return ;
        int m = (l + r) >> 1;
        if (ff.l <= m)
            querysegment(ff, lson);
        if (ff.r > m)
            querysegment(ff, rson);
        pushup(rt);
    }
    
    bool fir;
    void query(int l, int r, int rt) {
        if (node[rt]._max == node[rt]._min) {
            for (int i = l; i <= r; i++) {
                if (node[rt]._min == INF)
                    node[rt]._min = -1;
                if (!fir) {
                    printf("%lld", node[rt]._min);
                    fir = true;
                }
                else 
                    printf(" %lld", node[rt]._min);
            }
            return ;
        }
        if (l == r) {
            return ;
        }
        pushdown(rt);
        int m = (l + r) >> 1;
        query(lson);
        query(rson);
    }
    
    int main() {
    
        int t_case;
        scanf("%d", &t_case);
        for (int i_case = 1; i_case <= t_case; i_case++) {
            scanf("%d", &n);
            for (int i = 1; i <= n; i++)
                scanf("%d", &lef[i]);
            for (int i = 1; i <= n; i++)
                scanf("%d", &rig[i]);
            for (int i = 1; i <= n; i++)
                scanf("%lld", &c[i]);
            build(1, n, 1);
            while(!q.empty())
                q.pop();
    
            q.push(Segment(1, 1, 0));
            while (!q.empty()) {
                Segment ff = q.top();
                q.pop();
                querysegment(ff, 1, n, 1);
            }
    
            fir = false;
            query(1, n, 1);
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    转载 logback的使用和logback.xml详解 http://www.cnblogs.com/warking/p/5710303.html
    HTTP 416
    maven 下载jar失败: Missing artifact javax.jms:jms:jar:1.1
    maven 下载jar失败: resolution will not be reattempted until the update interval of central has elapsed or updates are forced
    Exception in thread "main" java.lang.UnsupportedClassVersionError: org/apache/maven/cli/MavenCli : Unsupported major.minor version 51.0
    转载 Servlet3 的 @WebServlet http://www.cnblogs.com/luxh/archive/2012/06/06/2537458.html
    mysqld服务启动失败, Failed to restart mysqld.service: Unit not found.
    <转载> 22种代码味道(Martin Fowler与Kent Beck) http://blog.csdn.net/lovelion/article/details/9301691
    再谈java clone 以及 浅/深拷贝
    设计模式——再谈工厂模式
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/8370725.html
Copyright © 2020-2023  润新知