zoukankan      html  css  js  c++  java
  • 【lct】bzoj2049 [Sdoi2008]Cave 洞穴勘测

    题意:维护一个动态并查集,支持加边,删边,维护两点连通性。

    主要用到了 lct 的 Access FindRoot ChangeRoot link cut 操作。

    #include<cstdio>
    #include<iostream>
    #include<stack>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define maxn 10005
    int fa[maxn],c[maxn][2],siz[maxn];
    bool is_root[maxn],delta[maxn];
    void Mark(int x){
        if(x){
            delta[x]^=1;
        }
    }
    void Maintain(int x)
    {
        siz[x]=siz[c[x][0]]+siz[c[x][1]]+1;
    }
    void pushdown(int x){
        if(delta[x]){
            Mark(c[x][0]);
            Mark(c[x][1]);
            swap(c[x][0],c[x][1]);
            delta[x]=0;
        }
    }
    void Rotate(int x,bool flag)
    {
        int y=fa[x];
        c[y][!flag]=c[x][flag];
        if(c[x][flag]){
            fa[c[x][flag]]=y;
        }
        if(fa[y] && c[fa[y]][c[fa[y]][1]==y]==y){
            c[fa[y]][c[fa[y]][1]==y]=x;
        }
        fa[x]=fa[y];
        c[x][flag]=y;
        fa[y]=x;
        if(is_root[y]){
            is_root[y]=0;
            is_root[x]=1;
        }
        Maintain(y);
        Maintain(x);
    }
    stack<int>st;
    void Splay(int x)
    {
        pushdown(x);
        if(!x || is_root[x]){
            return;
        }
        int U=x;
        while(!is_root[U]){
            st.push(U);
            U=fa[U];
        }
        st.push(U);
        while(!st.empty()){
            pushdown(st.top());
            st.pop();
        }
        int y;
        while(y=fa[x],(!is_root[x])){
            if(is_root[y]){
                Rotate(x,c[y][0]==x);
            }
            else{
                if((c[y][0]==x)==(c[fa[y]][0]==y)){
                    Rotate(y,c[fa[y]][0]==y);
                }
                else{
                    Rotate(x,c[y][0]==x);
                    y=fa[x];
                }
                Rotate(x,c[y][0]==x);
            }
        }
        Maintain(x);
    }
    void Access(int x){
        int y;
        Splay(x);
        while(fa[x]){
            y=fa[x];
            Splay(y);
            Splay(x);
            if(c[y][1]){
                is_root[c[y][1]]=1;
            }
            is_root[x]=0;
            c[y][1]=x;
            Splay(x);
        }
        if(c[x][1]){
            is_root[c[x][1]]=1;
            c[x][1]=0;
        }
    }
    void ChangeRoot(int x){
        Access(x);
        Splay(x);
        Mark(x);
    }
    void cut(int x){
        Access(x);
        Splay(x);
        fa[c[x][0]]=0;
        if(c[x][0]){
            is_root[c[x][0]]=1;
        }
        c[x][0]=0;
    }
    void link(int x,int y){
        Access(x);
        Splay(x);
    //  Mark(c[x][0]);
        Access(y);
        Splay(y);
        c[y][1]=x;
        fa[x]=y;
        is_root[x]=0;
    }
    int FindRoot(int x){
        Access(x);
        Splay(x);
        while(c[x][0]){
            x=c[x][0];
        }
        return x;
    }
    int n,m;
    int main(){
    //	freopen("bzoj2049.in","r",stdin);
    	char op[10];
    	int x,y;
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;++i){
    		siz[i]=1;
    		is_root[i]=1;
    	}
    	for(int i=1;i<=m;++i){
    		scanf("%s%d%d",op,&x,&y);
    		if(op[0]=='Q'){
    			puts(FindRoot(x)==FindRoot(y) ? "Yes" : "No");
    		}
    		else if(op[0]=='C'){
    			ChangeRoot(x);
    			link(x,y);
    		}
    		else{
    			if(FindRoot(x)==FindRoot(y)){
    				ChangeRoot(x);
    				cut(y);
    			}
    		}
    	}
    	return 0;
    }
  • 相关阅读:
    5.搜索-dfs、回溯、bfs
    4.排序算法
    3.二分查找
    2.双指针
    1.贪心算法
    【目录】leetcode刷题
    深度学习的优化与正则化
    什么是深度学习
    循环神经网络
    Failed to execute 'index' on 'IDBObjectStore': The specified index was not found.
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/7648310.html
Copyright © 2011-2022 走看看