BZOJ:2049: [Sdoi2008]Cave 洞穴勘测

题解:

LinkCutTree维护连通性

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

const int maxn=100009;

int n,m;

int fa[maxn],ch[maxn][2],rev[maxn];
int minit(){
	memset(fa,0,sizeof(fa));
	memset(ch,0,sizeof(ch));
	memset(rev,0,sizeof(rev));
}

inline int son(int x){
	return ch[fa[x]][1]==x;
}
inline int isroot(int x){
	return (ch[fa[x]][1]!=x)&&(ch[fa[x]][0]!=x);
}
inline int pushdown(int x){
	if(rev[x]){
		rev[ch[x][0]]^=1;
		rev[ch[x][1]]^=1;
		rev[x]^=1;
		swap(ch[x][0],ch[x][1]);
	}
}
int Down(int x){
	if(!isroot(x))Down(fa[x]);
	pushdown(x);
}

int Rotate(int x){
	int y=fa[x];
	int z=fa[y];
	int b=son(x),c=son(y);
	int a=ch[x][b^1];
	if(!isroot(y))ch[z][c]=x;
	fa[x]=z;
	if(a)fa[a]=y;
	ch[y][b]=a;
	fa[y]=x;ch[x][b^1]=y;
}

int Splay(int x){
	Down(x);
	while(!isroot(x)){
		int y=fa[x];
		int z=fa[y];
		if(isroot(y)){
			Rotate(x);
		}else{
			if(son(x)==son(y)){
				Rotate(y);Rotate(x);
			}else{
				Rotate(x);Rotate(x);
			}
		}
	}
}

int Access(int x){
	for(int t=0;x;t=x,x=fa[x]){
		Splay(x);ch[x][1]=t;
	}
}

int Evert(int x){
	Access(x);Splay(x);rev[x]^=1;
}

int Link(int x,int y){
	Evert(x);fa[x]=y;
}

int Cut(int x,int y){
	Evert(x);Access(y);Splay(y);
	fa[ch[y][0]]=0;ch[y][0]=0;
}

int getf(int x){
	Access(x);Splay(x);
	while(ch[x][0])x=ch[x][0];
	return x;
}

int main(){
	minit();
	scanf("%d%d",&n,&m);
	char opty[10];
	while(m--){
		scanf("%s",opty);
		int x,y;
		scanf("%d%d",&x,&y);
		if(opty[0]==‘Q‘){
			if(getf(x)==getf(y))printf("Yes\n");
			else printf("No\n");
		}
		if(opty[0]==‘C‘){
			Link(x,y);
		}
		if(opty[0]==‘D‘){
			Cut(x,y);
		}
	}
	return 0;
}

  

原文地址:https://www.cnblogs.com/zzyer/p/8179170.html

时间: 2024-10-10 19:37:48

BZOJ:2049: [Sdoi2008]Cave 洞穴勘测的相关文章

BZOJ 2049: [Sdoi2008]Cave 洞穴勘测

二次联通门 : BZOJ 2049: [Sdoi2008]Cave 洞穴勘测 其实指针也不是很慢 我的指针代码能吊打70%的数组 及80%的指针.... /* BZOJ 2049: [Sdoi2008]Cave 洞穴勘测 LCT 连边 删边 查询是否在同一树中时, 只需要一直向上跳 看看树根是否相同就好了 */ #include <cstdio> #include <cstdlib> #include <iostream> #define Max 400009 int

BZOJ 2049([Sdoi2008]Cave 洞穴勘测-LCT)[Template:LCT]

2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 10 Sec  Memory Limit: 259 MB Submit: 4809  Solved: 2141 [Submit][Status][Discuss] Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴.假如两个洞穴可以通过一条或者多条通道按一定顺序连接

[BZOJ 2049] [Sdoi2008] Cave 洞穴勘测 【LCT】

题目链接:BZOJ - 2049 题目分析 LCT的基本模型,包括 Link ,Cut 操作和判断两个点是否在同一棵树内. Link(x, y) : Make_Root(x); Splay(x); Father[x] = y; Cut(x, y) : Make_Root(x); Access(y); 断掉 y 和 Son[y][0]; 注意修改 Son[y][0] 的 isRoot 和 Father 判断 x, y 是否在同一棵数内,我们就看两个点所在树的根是否相同,使用 Find_Root()

BZOJ 2049 [Sdoi2008]Cave 洞穴勘测 LCT

题意:链接 方法: LCT 解析: 搞了一下午的LCT,这道题就当做第一道模板?题.然后大概写个理解总结什么的. 首先!splay不要写挂!不要写挂! 然后对于这道题.没有什么奇怪的操作. 只有两个操作,将两个节点连起来,将两个节点之间的连边断开. 每一次询问,询问两个节点是否连通. 听起来挺简单的,一下子就想到了并查集有没有! 然而发现并查集并不可以搞. 也许是我太弱,但是我真的不会并查集的分割. 所以还是老老实实来想LCT. LCT 顾名思义,Link Cut 是其比较有代表性的操作? 首先

BZOJ 题目2049: [Sdoi2008]Cave 洞穴勘测(link cut tree)

2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 10 Sec  Memory Limit: 259 MB Submit: 4698  Solved: 2107 [Submit][Status][Discuss] Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴.假如两个洞穴可以通过一条或者多条通道按一定顺序连接

【LCT】【SDOI 2008】【bzoj 2049】Cave 洞穴勘测

2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 10 Sec Memory Limit: 259 MB Submit: 4805 Solved: 2139 Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴.假如两个洞穴可以通过一条或者多条通道按一定顺序连接起来,那么这两个洞穴就是连通的,按顺序连接在一起的这些通

BZOJ 2049: [Sdoi2008]Cave 洞穴勘測 LCT

入门级LCT: 仅仅有 Cut Link 2049: [Sdoi2008]Cave 洞穴勘測 Time Limit: 10 Sec  Memory Limit: 259 MB Submit: 3073  Solved: 1379 [id=2049" style="color:blue; text-decoration:none">Submit][Status] Description 辉辉热衷于洞穴勘測.某天,他依照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘

【bzoj 2049】Cave 洞穴勘测

Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴.假如两个洞穴可以通过一条或者多条通道按一定顺序连接起来,那么这两个洞穴就是连通的,按顺序连接在一起的这些通道则被称之为这两个洞穴之间的一条路径.洞穴都十分坚固无法破坏,然而通道不太稳定,时常因为外界影响而发生改变,比如,根据有关仪器的监测结果,123号洞穴和127号洞穴之间有时会出现一条通

【BZOJ】2049 [Sdoi2008]Cave 洞穴勘测

[算法]Link-Cut Tree [题解]lct 不是很懂你们会压常数的>_<! #include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn=10010; int f[maxn],t[maxn][2],n,m; bool g[maxn]; bool isroot(int x) {return (t[f[x]][0]!=x&&am