HDU - 5361 In Touch 线段树 + 最短路 || 并查集 + 最短路

HDU - 5361

直接用线段树维护最短路, 每次取出最小的去扩展。

好像还有nb的并查集写法。

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
#define LL long long
#define LD long double
#define ull unsigned long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ALL(x) (x).begin(), (x).end()
#define fio ios::sync_with_stdio(false); cin.tie(0);

using namespace std;

const int N = 2e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-8;
const double PI = acos(-1);

template<class T, class S> inline void add(T &a, S b) {a += b; if(a >= mod) a -= mod;}
template<class T, class S> inline void sub(T &a, S b) {a -= b; if(a < 0) a += mod;}
template<class T, class S> inline bool chkmax(T &a, S b) {return a < b ? a = b, true : false;}
template<class T, class S> inline bool chkmin(T &a, S b) {return a > b ? a = b, true : false;}

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

int n, l[N], r[N], c[N];
LL ans[N];

struct SegmentTree {
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
    LL mn[N << 2], id[N << 2], lazy[N << 2];
    inline void pull(int rt) {
        if(mn[rt << 1] == -1) {
            mn[rt] = mn[rt << 1 | 1];
            id[rt] = id[rt << 1 | 1];
        }
        else if(mn[rt << 1 | 1] == -1) {
            mn[rt] = mn[rt << 1];
            id[rt] = id[rt << 1];
        }
        else if(mn[rt << 1] <= mn[rt << 1 | 1]) {
            mn[rt] = mn[rt << 1];
            id[rt] = id[rt << 1];
        }
        else {
            mn[rt] = mn[rt << 1 | 1];
            id[rt] = id[rt << 1 | 1];
        }
    }
    inline void push(int rt) {
        if(lazy[rt] < INF) {
            chkmin(mn[rt << 1], lazy[rt]);
            chkmin(mn[rt << 1 | 1], lazy[rt]);
            chkmin(lazy[rt << 1], lazy[rt]);
            chkmin(lazy[rt << 1 | 1], lazy[rt]);
            lazy[rt] = INF;
        }
    }
    void build(int l, int r, int rt) {
        lazy[rt] = INF;
        if(l == r) {
            mn[rt] = INF;
            id[rt] = l;
            return;
        }
        int mid = l + r >> 1;
        build(lson); build(rson);
        pull(rt);
    }
    void update(int L, int R, LL val, int l, int r, int rt) {
        if(R < l || r < L || R < L) return;
        if(L <= l && r <= R) {
            chkmin(mn[rt], val);
            chkmin(lazy[rt], val);
            return;
        }
        push(rt);
        int mid = l + r >> 1;
        update(L, R, val, lson);
        update(L, R, val, rson);
        pull(rt);
    }
} Tree;

int main() {
    int T; scanf("%d", &T);
    while(T--) {
        scanf("%d", &n);
        for(int i = 1; i <= n; i++) {
            scanf("%d", &l[i]);
            ans[i] = -1;
        }
        for(int i = 1; i <= n; i++) {
            scanf("%d", &r[i]);
        }
        for(int i = 1; i <= n; i++) {
            scanf("%d", &c[i]);
        }
        Tree.build(1, n, 1);
        Tree.update(1, 1, 0, 1, n, 1);
        int L, R;
        while(Tree.mn[1] != -1 && Tree.mn[1] != INF) {
            LL dis = Tree.mn[1];
            if(dis == INF) break;
            int u = Tree.id[1];
            ans[u] = dis;
            L = max(1, u - r[u]);
            R = u - l[u];
            Tree.update(L, R, dis + c[u], 1, n, 1);
            R = min(n, u + r[u]);
            L = u + l[u];
            Tree.update(L, R, dis + c[u], 1, n, 1);
            Tree.update(u, u, -1, 1, n, 1);
        }
        for(int i = 1; i <= n; i++) {
            printf("%lld%c", ans[i], " \n"[i == n]);
        }
    }
    return 0;
}

/*
*/

 

posted @ 2019-07-17 16:21  NotNight  阅读(163)  评论(0编辑  收藏  举报