[WC 2006] 水管局长

[题目链接]

          https://www.lydsy.com/JudgeOnline/problem.php?id=2594

[算法]

        首先离线 , 将删边操作转化为倒序加边

        假设我们已经维护出了一棵最小生成树T , 若加入了一条边(u , v , w) , 那么形成了一个环 ,考虑kruskal算法的执行过程 :

        若w < 环上的边权最大值 , 那么可以将(u , v , w)加入 , 并将环上边权最大的边删除

        可以使用LCT维护

        时间复杂度 : O(NlogN ^ 2) , 注意常数优化

[代码]

         

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 3e5 + 10;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;

struct edge
{
    int u ,  v , w;
} e[MAXN << 1];
struct query
{
    int type;
    int u , v;
} que[MAXN << 1];

int n , m , q;
int fa[MAXN];
bool flg[MAXN];

struct Link_Cut_Tree
{
    struct Node
    {
        int father , son[2] , mx , value , id;
        bool tag;
    } a[MAXN << 2];
    inline void update(int x)
    {
        a[x].mx = a[x].value;
        a[x].id = x;
        if (a[x].son[0])
        {
            if (a[a[x].son[0]].mx > a[x].mx)
            {
                a[x].mx = a[a[x].son[0]].mx;
                a[x].id = a[a[x].son[0]].id;
            }
        }
        if (a[x].son[1])
        {
            if (a[a[x].son[1]].mx > a[x].mx)
            {
                a[x].mx = a[a[x].son[1]].mx;
                a[x].id = a[a[x].son[1]].id;
            }
        }
    }
    inline void init()
    {
        for (int i = n + 1; i <= n + m + 1; i++)
        {
            a[i].mx = a[i].value = e[i - n].w;
            a[i].id = i;
        }
    }
    inline void pushdown(int x)
    {
        if (a[x].tag)
        {
            swap(a[x].son[0] , a[x].son[1]);
            a[a[x].son[0]].tag ^= 1;
            a[a[x].son[1]].tag ^= 1;
            a[x].tag = false;
        }
    }
    inline bool get(int x)
    {
        pushdown(a[x].father);
        return a[a[x].father].son[1] == x;
    }
    inline bool nroot(int x)
    {
        return a[a[x].father].son[0] == x | a[a[x].father].son[1] == x;
    }
    inline void rotate(int x)
    {
        int f = a[x].father , g = a[f].father;                        
        int tmpx = get(x) , tmpf = get(f);
        int w = a[x].son[tmpx ^ 1];
        if (nroot(f)) a[g].son[tmpf] = x;
        a[x].son[tmpx ^ 1] = f;
        a[f].son[tmpx] = w;
        if (w) a[w].father = f;
        a[f].father = x;
        a[x].father = g;
        update(f);
    }
    inline int find_root(int x)
    {
        access(x);
        splay(x);
        while (a[x].son[0])
        {
            pushdown(x);
            x = a[x].son[0];
        }
        return x;
    }
    inline void access(int x)
    {
        for (int y = 0; x; x = a[y = x].father)
        {
            splay(x);
            a[x].son[1] = y;
            update(x);
        }
    }
    inline void splay(int x)
    {
        int y = x , z = 0;
        static int st[MAXN];
        st[++z] = y;
        while (nroot(y)) st[++z] = y = a[y].father;
        while (z) pushdown(st[z--]);
        while (nroot(x))
        {
            int y = a[x].father , z = a[y].father;
            if (nroot(y))
                rotate((a[y].son[0] == x) ^ (a[z].son[0] == y) ? x : y);
            rotate(x);
        }
        update(x);
    }
    inline void split(int x , int y)
    {
        make_root(x);
        access(y);
        splay(y);    
    } 
    inline void make_root(int x)
    {
        access(x);
        splay(x);
        a[x].tag ^= true;
        pushdown(x);
    }
    inline void link(int x , int y)
    {
        make_root(x);
        if (find_root(y) != x) a[x].father = y;
    }
    inline void cut(int x , int y)
    {
        make_root(x);
        if (find_root(y) == x && a[x].father == y && !a[x].son[1])
        {
            a[x].father = a[y].son[0] = 0;
            update(y);
        }
    }
    inline int query(int x)
    {
        return a[x].id;
    }
} LCT;

template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
    T f = 1; x = 0;
    char c = getchar();
    for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
    for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
    x *= f;
}
inline bool cmp(edge a , edge b)
{
    return a.w < b.w;    
}
inline int get_root(int x)
{
    if (fa[x] == x) return x;
    else return fa[x] = get_root(fa[x]);
}

int main()
{
    
    read(n); read(m); read(q);
    for (int i = 1; i <= m; i++)
    {
        read(e[i].u);
        read(e[i].v);
        read(e[i].w);    
        if (e[i].u > e[i].v) swap(e[i].u , e[i].v);
    }
    sort(e + 1 , e + m + 1 , cmp);
    map< pair<int , int> , int> mp;
    for (int i = 1; i <= m; i++) 
        mp[make_pair(e[i].u , e[i].v)] = i;
    for (int i = 1; i <= q; i++)
    {
        read(que[i].type);
        read(que[i].u);
        read(que[i].v);
        if (que[i].u > que[i].v) swap(que[i].u , que[i].v);
        if (que[i].type == 2)
            flg[mp[make_pair(que[i].u , que[i].v)]] = true;
    }
    LCT.init();
    for (int i = 1; i <= n; i++) fa[i] = i;
    for (int i = 1; i <= m; i++)
    {
        if (flg[i]) continue;
        int su = get_root(e[i].u) , sv = get_root(e[i].v);
        if (su != sv)
        {
            fa[su] = sv;
            LCT.link(e[i].u , i + n);
            LCT.link(e[i].v , i + n);
        }
    }
    vector< int > ans;
    for (int i = q; i >= 1; i--)
    {
        if (que[i].type == 1)
        {
            LCT.split(que[i].u , que[i].v);
            ans.push_back(e[LCT.query(que[i].v) - n].w);    
        } else
        {
            LCT.split(que[i].u , que[i].v);
            int id = LCT.query(que[i].v);
            if (e[mp[make_pair(que[i].u , que[i].v)]].w < e[id - n].w)
            {
                LCT.cut(e[id - n].u , id);
                LCT.cut(e[id - n].v , id);
                LCT.link(que[i].u , mp[make_pair(que[i].u , que[i].v)] + n);
                LCT.link(que[i].v , mp[make_pair(que[i].u , que[i].v)] + n);
            }
        }
    }
    reverse(ans.begin() , ans.end());
    for (unsigned i = 0; i < ans.size(); i++) printf("%d\n" , ans[i]);
    
    return 0;
}

 

posted @ 2018-12-19 22:04  evenbao  阅读(245)  评论(0编辑  收藏  举报