1. 程式人生 > >BZOJ 2049 SDOI2008 洞穴勘測 LCT板子

BZOJ 2049 SDOI2008 洞穴勘測 LCT板子

tor 鏈接 http main map play int mes roo

題目鏈接:http://www.lydsy.com/JudgeOnline/problem.php?id=2049

題意概述:給出N個點,一開始不連通,M次操作,刪邊加邊,保證圖是一個森林,詢問兩點連通性。

N<=10000,M<=200000

實際上我就是想來放個LCT板子。。。。。。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<algorithm>
 6 #include<cmath>
 7
#include<queue> 8 #include<set> 9 #include<map> 10 #include<vector> 11 #include<cctype> 12 using namespace std; 13 14 int N,M; 15 struct link_cut_tree{ 16 static const int maxn=100005; 17 struct node{ 18 int ch[2],fa; bool res; 19 node(){ ch[0]=ch[1
]=fa=0,res=0; } 20 }nd[maxn]; 21 void init(int n) { for(int i=1;i<=n;i++) nd[i].ch[0]=nd[i].ch[1]=nd[i].fa=0,nd[i].res=0; } 22 void link(int x,int d,int y) { nd[x].ch[d]=y,nd[y].fa=x; } 23 bool isrt(int x) { return nd[nd[x].fa].ch[0]!=x&&nd[nd[x].fa].ch[1]!=x; } 24 void pushdown(int
x) 25 { 26 if(!nd[x].res) return; 27 int lc=nd[x].ch[0],rc=nd[x].ch[1]; 28 if(lc) nd[lc].res^=1,swap(nd[lc].ch[0],nd[lc].ch[1]); 29 if(rc) nd[rc].res^=1,swap(nd[rc].ch[0],nd[rc].ch[1]); 30 nd[x].res=0; 31 } 32 void rot(int x) 33 { 34 int y=nd[x].fa,z=nd[y].fa; 35 pushdown(y);pushdown(x); 36 if(!isrt(y)) link(z,nd[z].ch[1]==y,x); nd[x].fa=z; 37 int d=nd[y].ch[0]==x; 38 link(y,d^1,nd[x].ch[d]); 39 link(x,d,y); 40 } 41 void splay(int x) 42 { 43 pushdown(x); 44 while(!isrt(x)){ 45 int y=nd[x].fa,z=nd[y].fa; 46 if(!isrt(y)) rot((nd[y].ch[0]==x)==(nd[z].ch[0]==y)?y:x); 47 rot(x); 48 } 49 } 50 void access(int x) 51 { 52 int y=0; 53 while(x){ splay(x); nd[x].ch[1]=y,y=x,x=nd[x].fa; } 54 } 55 void mroot(int x) 56 { 57 access(x); splay(x); 58 nd[x].res^=1,swap(nd[x].ch[0],nd[x].ch[1]); 59 } 60 void Link(int x,int y) { mroot(x); nd[x].fa=y; } 61 void Cut(int x,int y) 62 { 63 mroot(x); access(y); splay(y); 64 nd[x].fa=nd[y].ch[0]=0; 65 } 66 int find(int x) 67 { 68 access(x); splay(x); 69 while(nd[x].ch[0]){ pushdown(nd[x].ch[0]); x=nd[x].ch[0]; } 70 return x; 71 } 72 }lct; 73 74 void work() 75 { 76 scanf("%d%d",&N,&M); 77 char op[10]; int x,y; 78 for(int i=1;i<=M;i++){ 79 scanf("%s%d%d",op,&x,&y); 80 if(op[0]==C) lct.Link(x,y); 81 else if(op[0]==D) lct.Cut(x,y); 82 else if(op[0]==Q) puts(lct.find(x)==lct.find(y)?"Yes":"No"); 83 } 84 } 85 int main() 86 { 87 work(); 88 return 0; 89 }

BZOJ 2049 SDOI2008 洞穴勘測 LCT板子