博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ2049 洞穴勘测(LCT)
阅读量:5151 次
发布时间:2019-06-13

本文共 2834 字,大约阅读时间需要 9 分钟。

【题目描述】

(太长也懒得复制了)

题目大意就是:给你N个点,这N个点一开始没有路径相连,然后给出M个操作,包含三个操作:

1.Query(x,y):询问x,y之间是否连通。

2.Connect(x,y):在x,y之间连一条边。

3.Destroy(x,y):将x,y之间的边删除。

最后对于每个Query,如果连通就输出"Yes",否则输出“No”。

【输入格式】

第一行为两个正整数n和m,分别表示洞穴的个数和终端机上出现过的指令的个数。以下m行,依次表示终端机上出现的各条指令。每行开头是一个表示指令种类的字符串s("Connect”、”Destroy”或者”Query”,区分大小写),之后有两个整数u和v (1≤u, v≤n且u≠v) 分别表示两个洞穴的编号。

【输出格式】

对每个Query指令,输出洞穴u和洞穴v是否互相连通:是输出”Yes”,否则输出”No”。(不含双引号)

【样例输入】

Connect 1 2

Connect 3 1

Query 2 3

Destroy 1 3

Query 2 3

【样例输出】

Yes

No

【备注】

10%的数据满足n≤1000, m≤20000

20%的数据满足n≤2000, m≤40000

30%的数据满足n≤3000, m≤60000

40%的数据满足n≤4000, m≤80000

50%的数据满足n≤5000, m≤100000

60%的数据满足n≤6000, m≤120000

70%的数据满足n≤7000, m≤140000

80%的数据满足n≤8000, m≤160000

90%的数据满足n≤9000, m≤180000

100%的数据满足n≤10000, m≤200000

保证所有Destroy指令将摧毁的是一条存在的通道

本题输入、输出规模比较大,建议c\c++选手使用scanf和printf进行I\O操作以免超时

【题目分析】

很裸的一道LCT题,命令只包含findroot、link、cut操作(但还是要把操作写完QAQ)

【代码~】

#include
using namespace std;const int MAXN=1e4+10;int n,m,u,v,qr,que[MAXN];struct node{ int fa,lc,rc; int rev;}tr[MAXN];bool which(const int &x){ return tr[tr[x].fa].rc==x;}bool isroot(const int &x){ if(!tr[x].fa) return true; return tr[tr[x].fa].lc!=x&&tr[tr[x].fa].rc!=x;}void push_down(const int &root){ if(tr[root].rev) { swap(tr[root].lc,tr[root].rc); if(tr[root].lc) tr[tr[root].lc].rev^=1; if(tr[root].rc) tr[tr[root].rc].rev^=1; tr[root].rev=0; }}void rotate(const int &x){ int y=tr[x].fa,z=tr[y].fa,b=tr[y].lc==x?tr[x].rc:tr[x].lc; if(z&&!isroot(y)) (tr[z].lc==y?tr[z].lc:tr[z].rc)=x; tr[x].fa=z,tr[y].fa=x,b?tr[b].fa=y:0; if(tr[y].lc==x) tr[x].rc=y,tr[y].lc=b; else tr[x].lc=y,tr[y].rc=b;}void splay(const int &x){ que[qr=0]=x; for(int y=x;!isroot(y);y=tr[y].fa) que[++qr]=tr[y].fa; for(int i=qr;i>=0;--i) push_down(que[i]); while(!isroot(x)) { if(!isroot(tr[x].fa)) { if(which(x)==which(tr[x].fa)) rotate(tr[x].fa); else rotate(x); } rotate(x); }}void access(int x){ for(int y=0;x;y=x,x=tr[x].fa) { splay(x); tr[x].rc=y; if(y) tr[y].fa=x; }}int findroot(int x){ access(x); splay(x); while(push_down(x),tr[x].lc) x=tr[x].lc; splay(x); return x;}void makeroot(int x){ access(x); splay(x); tr[x].rev=1;}void link(const int &x,const int &y){ makeroot(x); tr[x].fa=y;}void cut(const int &x,const int &y){ makeroot(x); access(y); splay(y); tr[y].lc=0; tr[x].fa=0;}int Read(){ int i=0,f=1; char c; for(c=getchar();(c>'9'||c<'0')&&c!='-';c=getchar()); if(c=='-') f=-1,c=getchar(); for(;c>='0'&&c<='9';c=getchar()) i=(i<<3)+(i<<1)+c-'0'; return i*f;}int main(){ scanf("%d%d",&n,&m); char ch; for(int i=1;i<=m;++i) { while(ch=getchar(),ch>'Z'||ch<'A'); if(ch=='Q') { if(findroot(Read())==findroot(Read())) printf("Yes\n"); else printf("No\n"); } else { if(ch=='C') link(Read(),Read()); else cut(Read(),Read()); } } return 0;}

 

转载于:https://www.cnblogs.com/Ishtar/p/10010824.html

你可能感兴趣的文章