zoukankan      html  css  js  c++  java
  • P4172 [WC2006]水管局长(LCT)

    P4172 [WC2006]水管局长

    LCT维护最小生成树,边权化点权。类似 P2387 [NOI2014]魔法森林(LCT)

    离线存储询问,倒序处理,删边改加边。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define rint register int
    using namespace std;
    inline void Swap(int &a,int &b){a^=b^=a^=b;}
    void read(int &x){
        static char c=getchar();x=0;
        while(c<'0'||c>'9') c=getchar();
        while('0'<=c&&c<='9') x=x*10+(c^48),c=getchar();
    }
    #define M 200005
    int n,m,Q,ch[M][2],fa[M],val[M],s[M],rev[M]; bool del[M];
    int mp[1005][1005],p1[M],p2[M],p3[M],q1[M],q2[M],q3[M],ans[M];
    #define lc ch[x][0]
    #define rc ch[x][1]
    inline bool nrt(int x){return ch[fa[x]][0]==x||ch[fa[x]][1]==x;}
    void up(int x){//维护最大边化为的点的编号
        s[x]=x;
        if(val[s[lc]]>val[s[x]]) s[x]=s[lc];
        if(val[s[rc]]>val[s[x]]) s[x]=s[rc];
    }
    inline void Rev(int x){Swap(lc,rc),rev[x]^=1;}
    void down(int x){if(rev[x])Rev(lc),Rev(rc),rev[x]^=1;}
    void Pre(int x){if(nrt(x))Pre(fa[x]); down(x);}
    void turn(int x){
        int y=fa[x],z=fa[y],l=(ch[y][1]==x),r=l^1;
        if(nrt(y)) ch[z][ch[z][1]==y]=x;
        fa[ch[x][r]]=y; fa[y]=x; fa[x]=z;
        ch[y][l]=ch[x][r]; ch[x][r]=y;
        up(y); up(x);
    }
    void splay(int x){
        Pre(x);
        for(;nrt(x);turn(x)){
            int y=fa[x],z=fa[y];
            if(nrt(y)) turn((ch[y][1]==z)^(ch[z][1]==y)?x:y);
        }
    }
    void access(int x){for(int y=0;x;y=x,x=fa[x])splay(x),rc=y,up(x);}
    inline void makert(int x){access(x),splay(x),Rev(x);}
    int findrt(int x){
        access(x);splay(x);down(x);
        while(lc) x=lc,down(x);
        splay(x); return x;
    }
    void link(int x,int y){makert(x); if(findrt(y)!=x) fa[x]=y;}
    void cut(int x,int y){
        makert(x);
        if(findrt(y)==x&&fa[y]==x&&!ch[y][0]) fa[y]=rc=0,up(x);
    }
    inline void split(int x,int y){makert(x),access(y),splay(y);}
    void ins(int i){
        bool is=1;
        if(findrt(p1[i])==findrt(p2[i])){//已经连在一起
            split(p1[i],p2[i]); int w=s[p2[i]];
            if(val[w]>p3[i])
                cut(p1[w-n],w),cut(w,p2[w-n]);//删除最大边
            else is=0;
        }if(is) link(p1[i],n+i),link(n+i,p2[i]);
    }
    int main(){
        read(n);read(m);read(Q);
        for(rint i=1;i<=m;++i){
            read(p1[i]),read(p2[i]),read(p3[i]);
            mp[p1[i]][p2[i]]=mp[p2[i]][p1[i]]=i;
            val[n+i]=p3[i];
        }
        for(rint i=1;i<=Q;++i){
            read(q1[i]),read(q2[i]),read(q3[i]);
            if(q1[i]==2) del[mp[q2[i]][q3[i]]]=1;
        }
        for(rint i=1;i<=m;++i) if(!del[i]) ins(i);
        for(rint i=Q;i>=1;--i){//倒序处理询问
            if(q1[i]==2) ins(mp[q2[i]][q3[i]]);
            else split(q2[i],q3[i]),ans[i]=val[s[q3[i]]];
        }
        for(rint i=1;i<=Q;++i) if(q1[i]==1) printf("%d
    ",ans[i]);
        return 0;
    }
  • 相关阅读:
    web测试方法总结
    APP测试点总结
    函数初识
    字符编码及文件操作
    简单购物车程序(Python)
    基本数据类型(列表,元祖,字典,集合)
    python基础
    基本数据类型(数字和字符串)
    Python入门
    操作系统
  • 原文地址:https://www.cnblogs.com/kafuuchino/p/10660288.html
Copyright © 2011-2022 走看看