【BZOJ2049】[Sdoi2008]Cave 洞穴勘测 Link-Cut-Tree

来源:互联网 发布:淘宝搞活动时间表2017 编辑:程序博客网 时间:2024/05/21 09:10

Link-Cut-Tree详细解释看这里 Link/cut tree From Wikipedia, the free encyclopedia .

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define N 10005#define inf 0x3f3f3f3fstruct splay{splay *fa,*ch[2];int v,rev;splay(int val=0){v=val; rev=0;}inline bool root(){return fa->ch[1]!=this&&fa->ch[0]!=this;}inline int check(){return fa->ch[1]==this;}inline void combine(splay *x,int d){ch[d]=x; x->fa=this;}void pushdown(){if(!root()) fa->pushdown();if(rev) reverse();}inline void reverse(){rev^=1;swap(ch[0],ch[1]);ch[0]->rev^=1; ch[1]->rev^=1;}}*null=new splay(),*tree[N];inline void rotate(splay *x){splay *k=x->fa;int d=!x->check();k->combine(x->ch[d],d^1);if(!k->root()) k->fa->ch[k->check()]=x;x->fa=k->fa;x->combine(k,d);}inline void Splay(splay *x){x->pushdown();while(!x->root()){if(!x->fa->root())rotate(x->check()^x->fa->check()?x:x->fa);rotate(x);}}void access(splay *x){splay *now=x,*pre=null;while(now!=null)Splay(now), now->ch[1]=pre,pre=now, now=now->fa;Splay(x);}void make_root(splay *x){access(x);x->rev^=1;}void link(splay *x,splay *y){make_root(x);x->fa=y;}void cut(splay *x,splay *y){make_root(x);access(y);x->fa=y->ch[0]=null;}int find_root(splay *x){access(x);while(x->ch[0]!=null)x=x->ch[0];return x->v;}int n,m;int main(){cin>>n>>m;char str[5];int u,v;for(int i=1;i<=n;i++)tree[i]=new splay(i),tree[i]->fa=tree[i]->ch[0]=tree[i]->ch[1]=null;while(m--){scanf("%s%d%d",str,&u,&v);switch(str[0]){case 'C': link(tree[u],tree[v]); break;case 'D': cut(tree[u],tree[v]); break;case 'Q': puts(find_root(tree[u])==find_root(tree[v])?"Yes":"No"); break;}}}


0 0