SDOI2008洞穴勘测--LCT入门

本文通过实战代码详细解析了链式切割树(Link Cut Tree, LCT)的基本操作及应用,包括翻转、下推、旋转等核心算法,并演示了如何实现节点查询、连接与切断等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

LCT真是太抽象了,sak(%%%)给我讲了一下,大概懂了但是还有很多存在漏洞的地方。显然,先发篇博客再慢慢看吧。。。。。。。。

#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=10005;
struct Link_Cut_Tree{
	bool rev[maxn];
	int fa[maxn],ch[maxn][2];
	void push_down(int p){
		if(rev[p]){
			rev[ch[p][0]]^=1;
			rev[ch[p][1]]^=1;
			swap(ch[p][0],ch[p][1]);
			rev[p]=0;
		}
	}
	void push(int u){
		if(!is_root(u))push(fa[u]);
		push_down(u);
	}
	bool is_root(int u){
		return (u!=ch[fa[u]][0])&&(u!=ch[fa[u]][1]);
	}
	void rotate(int u,int p,bool k){
		if(!is_root(p))
			ch[fa[p]][p==ch[fa[p]][1]]=u;
		fa[ch[u][k^1]]=p,fa[u]=fa[p],fa[p]=u;
		ch[p][k]=ch[u][k^1],ch[u][k^1]=p;
	}
	void splay(int u){
		push(u);
		while(!is_root(u))
			rotate(u,fa[u],u==ch[fa[u]][1]);
	}
	void access(int u){
		int v=0;
		while(u){
			splay(u);
			ch[u][1]=v;
			u=fa[v=u];
		}
	}
	void set_root(int u){
		access(u),splay(u);
		rev[u]^=1;
	}
	void link(int u,int v){
		set_root(u);
		fa[u]=v;
	}
	void cut(int u,int v){
		set_root(u);
		access(v),splay(v);
		fa[u]=ch[v][0]=0;
	}
	int find(int u){
		while(fa[u])u=fa[u];
		return u;
	}
	bool query(int u,int v){
		return find(u)==find(v);
	}
}T;
int main(){
	char ch[10];
	int n,m,u,v;
	scanf("%d%d",&n,&m);
	while(m--){
		scanf("%s%d%d",ch,&u,&v);
		if(ch[0]=='C')T.link(u,v);
		else if(ch[0]=='D')T.cut(u,v);
		else printf("%s\n",T.query(u,v)?"Yes":"No");
	}
	return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值