• 洛谷 P2387 [NOI2014]魔法森林


    传送门

    AcWing 999 魔法森林

    #include <bits/stdc++.h>
    
    using namespace std;
    using ll = long long;
    using p = pair<int, int>;
    const int inf(0x3f3f3f3f);
    const int maxn(15e4 + 10);
    int pre[maxn];
    
    struct node {
        int val, mx;
        int fa, ch[2];
        bool rev;
    } tree[maxn];
    
    struct edge {
        int x, y, a, b;
    } edges[maxn];
    
    template<typename T = int>
    inline const T read()
    {
        T x = 0, f = 1;
        char ch = getchar();
        while (ch < '0' or ch > '9') {
            if (ch == '-') f = -1;
            ch = getchar();
        }
        while (ch >= '0' and ch <= '9') {
            x = (x << 3) + (x << 1) + ch - '0';
            ch = getchar();
        }
        return x * f;
    }
    
    template<typename T>
    inline void write(T x, bool ln)
    {
        if (x < 0) {
            putchar('-');
            x = -x;
        }
        if (x > 9) write(x / 10, false);
        putchar(x % 10 + '0');
        if (ln) putchar(10);
    }
    
    inline int Find(int cur)
    {
        return pre[cur] == cur ? cur : pre[cur] = Find(pre[cur]);
    }
    
    inline void Union(int u, int v)
    {
        pre[Find(v)] = Find(u);
    }
    
    inline int& ls(int cur)
    {
        return tree[cur].ch[0];
    }
    
    inline int& rs(int cur)
    {
        return tree[cur].ch[1];
    }
    
    inline bool get_rel(int cur, int fa)
    {
        return rs(fa) == cur;
    }
    
    inline void connect(int cur, int fa, bool rel)
    {
        tree[fa].ch[rel] = cur;
        tree[cur].fa = fa;
    }
    
    inline bool is_root(int cur)
    {
        return ls(tree[cur].fa) not_eq cur and rs(tree[cur].fa) not_eq cur;
    }
    
    inline void reverse(int cur)
    {
        swap(ls(cur), rs(cur));
        tree[cur].rev xor_eq 1;
    }
    
    inline void push_up(int cur)
    {
        tree[cur].mx = cur;
        if (tree[tree[ls(cur)].mx].val > tree[tree[cur].mx].val) {
            tree[cur].mx = tree[ls(cur)].mx;
        }
        if (tree[tree[rs(cur)].mx].val > tree[tree[cur].mx].val) {
            tree[cur].mx = tree[rs(cur)].mx;
        }
    }
    
    inline void push_down(int cur)
    {
        if (tree[cur].rev) {
            reverse(ls(cur));
            reverse(rs(cur));
            tree[cur].rev = false;
        }
    }
    
    inline void push_all(int cur)
    {
        if (not is_root(cur)) {
            push_all(tree[cur].fa);
        }
        push_down(cur);
    }
    
    inline void rotate(int cur)
    {
        int fa = tree[cur].fa;
        int gf = tree[fa].fa;
        bool rel = get_rel(cur, fa);
        connect(tree[cur].ch[rel xor 1], fa, rel);
        tree[cur].fa = gf;
        if (not is_root(fa)) {
            tree[gf].ch[get_rel(fa, gf)] = cur;
        }
        connect(fa, cur, rel xor 1);
        push_up(fa);
        push_up(cur);
    }
    
    inline void splaying(int cur)
    {
        push_all(cur);
        while (not is_root(cur)) {
            int fa = tree[cur].fa;
            int gf = tree[cur].fa;
            if (not is_root(fa)) {
                get_rel(cur, fa) xor get_rel(fa, gf) ? rotate(cur) : rotate(fa);
            }
            rotate(cur);
        }
    }
    
    inline void access(int cur)
    {
        for (int pre = 0; cur; cur = tree[cur].fa) {
            splaying(cur);
            rs(cur) = pre;
            push_up(cur);
            pre = cur;
        }
    }
    
    inline void make_root(int cur)
    {
        access(cur);
        splaying(cur);
        reverse(cur);
    }
    
    inline int find_root(int cur)
    {
        access(cur);
        splaying(cur);
        while (ls(cur)) {
            push_down(cur);
            cur = ls(cur);
        }
        splaying(cur);
        return cur;
    }
    
    inline void link(int u, int v)
    {
        make_root(u);
        if (find_root(v) not_eq u) {
            tree[u].fa = v;
        }
    }
    
    inline void cut(int u, int v)
    {
        make_root(u);
        if (find_root(v) == u and tree[v].fa == u and not ls(v)) {
            rs(u) = tree[v].fa = 0;
            push_up(u);
        }
    }
    
    inline void split(int u, int v)
    {
        make_root(u);
        access(v);
        splaying(v);
    }
    
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("input.txt", "r", stdin);
    #endif
        int n = read(), m = read();
        for (int i = 1; i <= m; ++i) {
            edges[i].x = read();
            edges[i].y = read();
            edges[i].a = read();
            edges[i].b = read();
        }
        sort(edges + 1, edges + m + 1, [&](const edge& a, const edge& b) {
            return a.a < b.a;
        });
        for (int i = 1; i <= n + m; ++i) {
            pre[i] = i;
            if (i > n) {
                tree[i].val = edges[i - n].b;
            }
            tree[i].mx = i;
        }
        int res = inf;
        for (int i = 1; i <= m; ++i) {
            int u = edges[i].x, v = edges[i].y;
            int a = edges[i].a, b = edges[i].b;
            if (Find(u) == Find(v)) {
                split(u, v);
                int t = tree[v].mx;
                if (tree[t].val > b) {
                    cut(edges[t - n].x, t);
                    cut(t, edges[t - n].y);
                    link(u, n + i);
                    link(n + i, v);
                }
            } else {
                Union(u, v);
                link(u, n + i);
                link(n + i, v);
            }
            if (Find(1) == Find(n)) {
                split(1, n);
                res = min(res, a + tree[tree[n].mx].val);
            }
        }
        write(res == inf ? -1 : res, true);
        return 0;
    }
    
  • 相关阅读:
    关于centos防火墙
    linux基础命令
    mysql经典语句
    异常处理
    抽象类
    特性-多态
    特性-继承
    特性-封装
    python模块/文件/日期时间
    python函数3-函数嵌套/递归/匿名函数
  • 原文地址:https://www.cnblogs.com/singularity2u/p/14076663.html
Copyright © 2020-2023  润新知