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 0x3f3f3f3f struct 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; } } }