【刷题】BZOJ 4998 星球联盟
Description
在遥远的S星系中一共有N个星球,编号为1…N。其中的一些星球决定组成联盟,以方便相互间的交流。但是,组成联盟的首要条件就是交通条件。初始时,在这N个星球间有M条太空隧道。每条太空隧道连接两个星球,使得它们能够相互到达。若两个星球属于同一个联盟,则必须存在一条环形线路经过这两个星球,即两个星球间存在两条没有公共隧道的路径。为了壮大联盟的队伍,这些星球将建设P条新的太空隧道。这P条新隧道将按顺序依次建成。一条新轨道建成后,可能会使一些星球属于同一个联盟。你的任务是计算出,在一条新隧道建设完毕后,判断这条新轨道连接的两个星球是否属于同一个联盟,如果属于同一个联盟就计算出这个联盟中有多少个星球。
Input
第1行三个整数N,M和P,分别表示总星球数,初始时太空隧道的数目和即将建设的轨道数目。
第2至第M+1行,每行两个整数,表示初始时的每条太空隧道连接的两个星球编号。
第M+2行至第M+P+1行,每行两个整数,表示新建的太空隧道连接的两个星球编号。
这些太空隧道按照输入的顺序依次建成。
1≤N,M,P≤200000
Output
输出共P行。
如果这条新的太空隧道连接的两个星球属于同一个联盟,就输出一个整数,表示这两个星球所在联盟的星球数。
如果这条新的太空隧道连接的两个星球不属于同一个联盟,就输出"No"(不含引号)。
Sample Input
5 3 4
1 2
4 3
4 5
2 3
1 3
4 5
2 4
Sample Output
No
3
2
5
HINT
.png)
Solution
又是一个LCT的特殊操作——维护边双
其实就是缩点
LCT里真正维护的是那些缩了点之后的联通块的信息,称之为天人交战,与原图中的单个节点毫无关系(除了本身是一个联通块的),它的层次高那么一层
所以每次调用LCT的函数之前,都要先找到它所属的联通块的编号,再用这个编号在LCT里进行操作。那么每次跳节点的时候,要保证操作的节点是在天人层次,每次就跳到那个节点指向的联通块上去
如何记录每个点所属的联通块?用一个类似并查集的东西,记录它指向的联通块
然后在LCT外用一个真正的并查集记录两点的连通性
对于维护联通块,如果 \(u\) , \(v\) 已经联通,再要连上一条边,那肯定就有环了,也就有边双了,那这一个环里的联通块全都要缩起来,那就一个dfs,遍历环里的所有联通块,把他们都指向一个联通块就行了,同时维护题目要求的size
#include<bits/stdc++.h>
#define ll long long
#define db double
#define ld long double
const int MAXN=200000+10;
int n,m,p,fa[MAXN];
#define lc(x) ch[(x)][0]
#define rc(x) ch[(x)][1]
struct LCT{
	int ch[MAXN][2],fa[MAXN],rev[MAXN],size[MAXN],stack[MAXN],cnt,bel[MAXN];
	inline void init()
	{
		for(register int i=1;i<=n;++i)bel[i]=i,size[i]=1;
	}
	inline int find(int x)
	{
		return bel[x]==x?x:bel[x]=find(bel[x]);
	}
	inline bool nroot(int x)
	{
		return lc(find(fa[x]))==x||rc(find(fa[x]))==x;
	}
	inline void reverse(int x)
	{
		std::swap(lc(x),rc(x));
		rev[x]^=1;
	}
	inline void dfs(int x,int rt)
	{
		if(lc(x))dfs(lc(x),rt);
		if(rc(x))dfs(rc(x),rt);
		if(x!=rt)bel[x]=rt,size[rt]+=size[x];
	}
	inline void pushdown(int x)
	{
		if(rev[x])
		{
			if(lc(x))reverse(lc(x));
			if(rc(x))reverse(rc(x));
			rev[x]=0;
		}
	}
	inline void rotate(int x)
	{
		int f=find(fa[x]),p=find(fa[f]),c=(rc(f)==x);
		if(nroot(f))ch[p][rc(p)==f]=x;
		fa[ch[f][c]=ch[x][c^1]]=f;
		fa[ch[x][c^1]=f]=x;
		fa[x]=p;
	}
	inline void splay(int x)
	{
		cnt=0;
		stack[++cnt]=x;
		for(register int i=x;nroot(i);i=find(fa[i]))stack[++cnt]=find(fa[i]);
		while(cnt)pushdown(stack[cnt--]);
		for(register int y=find(fa[x]);nroot(x);rotate(x),y=find(fa[x]))
			if(nroot(y))rotate((lc(y)==x)==(lc(find(fa[y]))==y)?y:x);
	}
	inline void access(int x)
	{
		for(register int y=0;x;x=find(fa[y=x]))splay(x),rc(x)=y;
	}
	inline void makeroot(int x)
	{
		access(x);splay(x);reverse(x);
	}
	inline void split(int x,int y)
	{
		makeroot(x);access(y);splay(y);
	}
	inline void link(int x,int y)
	{
		makeroot(x);fa[x]=y;
	}
};
LCT T;
#undef lc
#undef rc
template<typename T> inline void read(T &x)
{
	T data=0,w=1;
	char ch=0;
	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
	if(ch=='-')w=-1,ch=getchar();
	while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
	x=data*w;
}
template<typename T> inline void write(T x,char c='\0')
{
	if(x<0)putchar('-'),x=-x;
	if(x>9)write(x/10);
	putchar(x%10+'0');
	if(c!='\0')putchar(c);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
inline int found(int x)
{
	if(fa[x]!=x)fa[x]=found(fa[x]);
	return fa[x];
}
inline int add(int u,int v)
{
	u=T.find(u),v=T.find(v);
	int x=found(u),y=found(v);
	if(u==v)return T.size[v];
	if(x!=y)
	{
		fa[x]=y,T.link(u,v);
		return -1;
	}
	T.split(u,v);T.dfs(T.ch[v][0],v);
	return T.size[v];
}
int main()
{
	read(n);read(m);read(p);
	T.init();
	for(register int i=1;i<=n;++i)fa[i]=i;
	for(register int i=1;i<=m;++i)
	{
		int u,v;
		read(u);read(v);
		add(u,v);
	}
	while(p--)
	{
		int u,v,res;
		read(u);read(v);
		if(~(res=add(u,v)))write(res,'\n');
		else puts("No");
	}
	return 0;
}
【刷题】BZOJ 4998 星球联盟的更多相关文章
- bzoj 4998 星球联盟
		新技能 get √ :LCT 维护边双连通分量 这题题意就是动态加边,每次求边的两端是否在一个边双连通分量里,输出 "No" 或者边双连通分量的大小 可以用两个并查集分别记录连通性 ... 
- 【刷题】BZOJ 2407 探险
		Description 探险家小T好高兴!X国要举办一次溶洞探险比赛,获奖者将得到丰厚奖品哦!小T虽然对奖品不感兴趣,但是这个大振名声的机会当然不能错过! 比赛即将开始,工作人员说明了这次比赛的规则: ... 
- 【刷题】BZOJ 4543 [POI2014]Hotel加强版
		Description 同OJ3522 数据范围:n<=100000 Solution dp的设计见[刷题]BZOJ 3522 [Poi2014]Hotel 然后发现dp的第二维与深度有关,于是 ... 
- 【刷题】BZOJ 4316 小C的独立集
		Description 图论小王子小C经常虐菜,特别是在图论方面,经常把小D虐得很惨很惨. 这不,小C让小D去求一个无向图的最大独立集,通俗地讲就是:在无向图中选出若干个点,这些点互相没有边连接,并使 ... 
- 【刷题】BZOJ 4176 Lucas的数论
		Description 去年的Lucas非常喜欢数论题,但是一年以后的Lucas却不那么喜欢了. 在整理以前的试题时,发现了这样一道题目"求Sigma(f(i)),其中1<=i< ... 
- BZOJ第一页刷题计划
		BZOJ第一页刷题计划 已完成:67 / 90 [BZOJ1000]A+B Problem:A+B: [BZOJ1001][BeiJing2006]狼抓兔子:最小割: [BZOJ1002][FJOI2 ... 
- 【刷题】BZOJ 2260 商店购物
		Description Grant是一个个体户老板,他经营的小店因为其丰富的优惠方案深受附近居民的青睐,生意红火.小店的优惠方案十分简单有趣.Grant规定:在一次消费过程中,如果您在本店购买了精制油 ... 
- 【刷题】BZOJ 4566 [Haoi2016]找相同字符
		Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两个子串中有一个位置不同. Input 两行,两个字符串s1,s2,长度分别为 ... 
- 【刷题】BZOJ 3365 [Usaco2004 Feb]Distance Statistics 路程统计
		Description 在得知了自己农场的完整地图后(地图形式如前三题所述),约翰又有了新的问题.他提供 一个整数K(1≤K≤109),希望你输出有多少对农场之间的距离是不超过K的. Input 第1 ... 
随机推荐
- python包管理工具pip
			你可以使用一个名为 pip 的程序来安装.升级和移除软件包.默认情况下 pip 将从 Python Package Index <https://pypi.org> 安装软件包.你可以在浏 ... 
- Linux下出现permission denied的解决办法
			Linux下经常出现permission denied,原因是由于权限不足,有很多文章通过chmod命令更改权限为777,但是很不方便也不适合新手,简单粗暴的方法如下: 命令行中输入 sudo pas ... 
- PHP核心技术——异常和错误处理
			PHP只有手动抛出异常后才能捕获异常 $a = null; try { $a = 5/0; echo $a,PHP_EOL; } catch (exception $e) { $e -> get ... 
- 学习python,第二篇
			注释 # 单行注释 ''' 多行注释 ''' 或者 """ 多行注释 """ # Author: Itxpl mag ... 
- Netty源码分析第7章(编码器和写数据)---->第1节: writeAndFlush的事件传播
			Netty源码分析第七章: 编码器和写数据 概述: 上一小章我们介绍了解码器, 这一章我们介绍编码器 其实编码器和解码器比较类似, 编码器也是一个handler, 并且属于outbounfHandle ... 
- 关于Maven的一点理解
			maven是一个项目管理工具,主要作用是: 1.依赖管理(jar包,工程之间); 2.统一开发规范和工具.完成项目的一步构建 3.工程聚合.继承.依赖 其核心配置文件就是pom.xml:pom即Pro ... 
- Redis Jedis简介
			Redis是一种基于内存类型的数据存储工具 Jedis是一个用java写的Redis数据库操作的客户端,通过Jedis,可以很方便的对redis数据库进行操作.Jedis通过Jedis Pool进行R ... 
- crosstool-ng搭建交叉编译环境注意事项
			一,crosstool-ng的下载及编译方法 可以参考如下网站: http://www.crosstool-ng.org/ 二,编译过程注意事项 1)如果遇到有些代码包不能下载,请依据指定版本,在这里 ... 
- jobs命令详解
			基础命令学习目录首页 在用管理员执行一个命令后,用Ctrl+Z把命令转移到了后台.导致无法退出root的. 输入命令:exit终端显示:There are stopped jobs. 解决方法:方法一 ... 
- alpha版postmortem 报告
			一.团队开发存在的问题 此次会议我们团队中每个成员都仔细思考并提出了团队在这一阶段存在的问题,主要如下: 1.前期任务规划.分配不合适: 2.个人对认领任务模块完成度.了解度不够: 3.个人学习意识. ... 
