HYSBZ 2049 Cave 洞穴勘测

比较简单的LCT,就一个link,Cut操作(就是HDU那道题中的两个),直接上代码:

#include 
#include 
#include 
#include 
#include 
#define LL long long
#define INF 0x3fffffff
#define FOR(i,x,y)  for(int i = x;i < y;i ++)
#define IFOR(i,x,y) for(int i = x;i > y;i --)
#define MAXN 11000

using namespace std;

int n,q;

struct LCT{
    int pre[MAXN],ch[MAXN][2];
    int flip[MAXN];
    bool rt[MAXN];

    void Update_Flip(int x){
        if(!x)  return;
        swap(ch[x][0],ch[x][1]);
        flip[x] ^= 1;
    }

    void Init(){
        memset(ch,0,sizeof(ch));
        memset(flip,0,sizeof(flip));
        memset(pre,0,sizeof(pre));
        memset(rt,true,sizeof(rt));
    }

    void PushUp(int x){
    }

    void PushDown(int x){
        if(flip[x]){
            if(ch[x][0])    Update_Flip(ch[x][0]);
            if(ch[x][1])    Update_Flip(ch[x][1]);
            flip[x] = 0;
        }
    }

    void Rotate(int x,int kind){
        int y = pre[x];
        PushDown(y);
        PushDown(x);
        ch[y][!kind] = ch[x][kind];
        if(ch[x][kind]) pre[ch[x][kind]] = y;
        if(rt[y]){
            rt[x] = true;
            rt[y] = false;
        }
        else{
            if(ch[pre[y]][1] == y)  ch[pre[y]][1] = x;
            if(ch[pre[y]][0] == y)  ch[pre[y]][0] = x;
        }
        pre[x] = pre[y];
        pre[y] = x;
        ch[x][kind] = y;
        PushUp(y);
    }

    void Splay(int x){
        PushDown(x);
        while(!rt[x]){
            int y = pre[x];
            int z = pre[y];
            PushDown(z); PushDown(y); PushDown(x);
            if(rt[y]){
                Rotate(x,ch[y][0] == x);
            }
            else{
                int kind = ch[z][0] == y;
                if(ch[y][kind] == x){
                    Rotate(x,!kind);
                    Rotate(x,kind);
                }
                else{
                    Rotate(y,kind);
                    Rotate(x,kind);
                }
            }
        }
        PushUp(x);
    }

    void Access(int x){
        int fa = 0;
        for(;x;x = pre[fa = x]){
            Splay(x);
            rt[ch[x][1]] = true;
            rt[ch[x][1] = fa] = false;
            PushUp(x);
        }
    }

    int GetRoot(int x){
        Access(x);
        Splay(x);
        while(ch[x][0]) x = ch[x][0];
        return x;
    }

    void MakeRoot(int x){
        Access(x);
        Splay(x);
        Update_Flip(x);
    }

    bool Link(int u,int v){
        if(GetRoot(u) == GetRoot(v))    return false;
        MakeRoot(u);
        pre[u] = v;
        Access(u);
        return true;
    }

    bool Cut(int u,int v){
        if(u == v || GetRoot(u) != GetRoot(v))    return false;
        MakeRoot(u);
        Access(v);
        Splay(v);
        if(ch[v][0])    pre[ch[v][0]] = pre[v],rt[ch[v][0]] = true;
        pre[v] = 0;
        ch[v][0] = 0;
        PushUp(v);
        return true;
    }

    bool Query(int u,int v){
        if(GetRoot(u) == GetRoot(v))    return true;
        return false;
    }

}lct;

int main(){
    //freopen("test.in","r",stdin);
    while(~scanf("%d%d",&n,&q)){
        lct.Init();
        char op[10];
        int u,v;
        FOR(i,0,q){
            scanf("%s%d%d",op,&u,&v);
            if(!strcmp(op,"Connect")){
                lct.Link(u,v);
            }
            else if(!strcmp(op,"Destroy")){
                lct.Cut(u,v);
            }
            else{
                if(lct.Query(u,v)){
                    printf("Yes\n");
                }
                else
                    printf("No\n");
            }
        }
    }
    return 0;
}


你可能感兴趣的:(动态树LCT)