码迷,mamicode.com
首页 > 其他好文 > 详细

动态树 LCT

时间:2015-08-18 14:04:02      阅读:286      评论:0      收藏:0      [点我收藏+]

标签:

bzoj2049 洞穴探测

题目大意:lct(link,cut,判联通)。

技术分享
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define maxnode 10005
using namespace std;
struct lct{
    int fa[maxnode],ch[maxnode][2],rev[maxnode],zh[maxnode];
    void init()
    {
        memset(fa,0,sizeof(fa));
        memset(ch,0,sizeof(ch));
        memset(rev,0,sizeof(rev));
    }
    bool isroot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
    int isd(int x){return x==ch[fa[x]][1];}
    void pushdown(int x)
    {
        int l,r;l=ch[x][0];r=ch[x][1];
        if (rev[x])
        {
            rev[x]^=1;rev[l]^=1;rev[r]^=1;
            swap(ch[x][0],ch[x][1]);
        }
    }
    void rotate(int x)
    {
        int y,z,d,l,r;y=fa[x];z=fa[y];
        if (ch[y][0]==x) l=0;
        else l=1; r=l^1;
        if (!isroot(y))
        {
            if (ch[z][0]==y) ch[z][0]=x;
            else ch[z][1]=x;
        }
        fa[x]=z;fa[y]=x;fa[ch[x][r]]=y;
        ch[y][l]=ch[x][r];ch[x][r]=y;
    }
    void splay(int x)
    {
        int i,top=0,y,z;zh[++top]=x;
        for (i=x;!isroot(i);i=fa[i]) zh[++top]=fa[i];
        for (i=top;i>=1;--i) pushdown(zh[i]);
        while(!isroot(x))
        {
            y=fa[x];z=fa[y];
            if (!isroot(y))
            {
                if (isd(x)==isd(y)) rotate(y);
                else rotate(x);
            }
            rotate(x);
        }
    }
    void access(int x)
    {
        int y=0;
        while(x){splay(x);ch[x][1]=y;y=x;x=fa[x];}
    }
    void makert(int x){access(x);splay(x);rev[x]^=1;}
    void link(int x,int y){makert(x);fa[x]=y;access(x);}
    void cut(int x,int y)
    {
       makert(x);access(y);splay(y);
       ch[y][0]=fa[x]=0;
    }
    int find(int x)
    {
        access(x);splay(x);
        int y=x;
        while(ch[y][0]) y=ch[y][0];
        return y;
    }
}tree;
char ss[10];
int main()
{
    int n,m,i,j,u,v;
    scanf("%d%d",&n,&m);tree.init();
    for (i=1;i<=m;++i)
    {
        scanf("%s",&ss);
        if (ss[0]==Q)
        {
            scanf("%d%d",&u,&v);
            if (tree.find(u)==tree.find(v)) printf("Yes\n");
            else printf("No\n");
        }
        if (ss[0]==C){scanf("%d%d",&u,&v);tree.link(u,v);}
        if (ss[0]==D){scanf("%d%d",&u,&v);tree.cut(u,v);}
    }
}
View Code

 

动态树 LCT

标签:

原文地址:http://www.cnblogs.com/Rivendell/p/4739132.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!