题目描述

在遥远的S星系中一共有N个星球,编号为1…N。其中的一些星球决定组成联盟,以方便相互间的交流。但是,组成联盟的首要条件就是交通条件。初始时,在这N个星球间有M条太空隧道。每条太空隧道连接两个星球,使得它们能够相互到达。若两个星球属于同一个联盟,则必须存在一条环形线路经过这两个星球,即两个星球间存在两条没有公共隧道的路径。为了壮大联盟的队伍,这些星球将建设P条新的太空隧道。这P条新隧道将按顺序依次建成。一条新轨道建成后,可能会使一些星球属于同一个联盟。你的任务是计算出,在一条新隧道建设完毕后,判断这条新轨道连接的两个星球是否属于同一个联盟,如果属于同一个联盟就计算出这个联盟中有多少个星球。

输入

第1行三个整数N,M和P,分别表示总星球数,初始时太空隧道的数目和即将建设的轨道数目。
第2至第M+1行,每行两个整数,表示初始时的每条太空隧道连接的两个星球编号。
第M+2行至第M+P+1行,每行两个整数,表示新建的太空隧道连接的两个星球编号。
这些太空隧道按照输入的顺序依次建成。
1≤N,M,P≤200000

输出

输出共P行。
如果这条新的太空隧道连接的两个星球属于同一个联盟,就输出一个整数,表示这两个星球所在联盟的星球数。
如果这条新的太空隧道连接的两个星球不属于同一个联盟,就输出"No"(不含引号)。

样例输入

5 3 4
1 2
4 3
4 5
2 3
1 3
4 5
2 4

样例输出

No
3
2
5


题解

LCT+并查集,【bzoj2959】长跑 的简化版。

由于只有加边没有删边,因此可以使用LCT维护连通关系,如果加入的一条边属于同一个连通块内,那么将他们之间的点缩成一个点。使用并查集维护连通关系和属于的点。

注意每次找fa时都需要find一遍,以找到真正的fa。

#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 200010
using namespace std;
int bl[N] , fa[N] , c[2][N] , w[N] , rev[N] , con[N];
int find(int x)
{
return x == bl[x] ? x : bl[x] = find(bl[x]);
}
int getcon(int x)
{
return x == con[x] ? x : con[x] = getcon(con[x]);
}
void pushdown(int x)
{
if(rev[x])
{
int l = c[0][x] , r = c[1][x];
swap(c[0][l] , c[1][l]) , swap(c[0][r] , c[1][r]);
rev[l] ^= 1 , rev[r] ^= 1 , rev[x] = 0;
}
}
bool isroot(int x)
{
return c[0][find(fa[x])] != x && c[1][find(fa[x])] != x;
}
void update(int x)
{
if(!isroot(x)) update(find(fa[x]));
pushdown(x);
}
void rotate(int x)
{
int y = find(fa[x]) , z = find(fa[y]) , l = (c[1][y] == x) , r = l ^ 1;
if(!isroot(y)) c[c[1][z] == y][z] = x;
fa[x] = z , fa[y] = x , fa[c[r][x]] = y , c[l][y] = c[r][x] , c[r][x] = y;
}
void splay(int x)
{
int y , z;
update(x);
while(!isroot(x))
{
y = find(fa[x]) , z = find(fa[y]);
if(!isroot(y))
{
if((c[0][y] == x) ^ (c[0][z] == y)) rotate(x);
else rotate(y);
}
rotate(x);
}
}
void access(int x)
{
int t = 0;
while(x) splay(x) , c[1][x] = t , t = x , x = find(fa[x]);
}
void makeroot(int x)
{
access(x) , splay(x) , swap(c[0][x] , c[1][x]) , rev[x] ^= 1;
}
void link(int x , int y)
{
makeroot(x) , fa[x] = y , con[getcon(x)] = getcon(y);
}
void dfs(int x , int y)
{
if(!x) return;
bl[x] = y , w[y] += w[x];
dfs(c[0][x] , y) , dfs(c[1][x] , y);
}
int add(int x , int y)
{
x = find(x) , y = find(y);
if(x == y) return w[x];
else if(getcon(x) != getcon(y))
{
link(x , y);
return -1;
}
makeroot(x) , access(y) , splay(y);
dfs(c[0][y] , y);
return w[y];
}
int main()
{
int n , m , p , i , x , y , t;
scanf("%d%d%d" , &n , &m , &p);
for(i = 1 ; i <= n ; i ++ ) bl[i] = con[i] = i , w[i] = 1;
for(i = 1 ; i <= m ; i ++ ) scanf("%d%d" , &x , &y) , add(x , y);
for(i = 1 ; i <= p ; i ++ )
{
scanf("%d%d" , &x , &y) , t = add(x , y);
if(~t) printf("%d\n" , t);
else puts("No");
}
return 0;
}

  

【bzoj4998】星球联盟 LCT+并查集的更多相关文章

  1. BZOJ4998星球联盟——LCT+并查集(LCT动态维护边双连通分量)

    题目描述 在遥远的S星系中一共有N个星球,编号为1…N.其中的一些星球决定组成联盟,以方便相互间的交流.但是,组成 联盟的首要条件就是交通条件.初始时,在这N个星球间有M条太空隧道.每条太空隧道连接两 ...

  2. bzoj4998 星球联盟 LCT + 并查集

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4998 题解 根据题意,就是要动态维护点双,求出一个点双的权值和. 所以这道题就是和 bzoj2 ...

  3. 【bzoj4998】星球联盟(并查集+边双)

    题面 传送门 题解 总算有自己的\(bzoj\)账号啦! 话说这题好像\(Scape\)去年暑假就讲过--然而我到现在才会-- \(LCT\)什么的跑得太慢了而且我也不会,所以这里是一个并查集的做法 ...

  4. bzoj4998 星球联盟

    bzoj4998 星球联盟 原题链接 题解 先按照输入顺序建一棵树(森林),然后用一个并查集维护联盟的关系,对于不是树上的边\(a-b\),就把\(a-lca(a,b),b-lca(a,b)\)全部合 ...

  5. 【bzoj2959】长跑 LCT+并查集

    题目描述 某校开展了同学们喜闻乐见的阳光长跑活动.为了能“为祖国健康工作五十年”,同学们纷纷离开寝室,离开教室,离开实验室,到操场参加3000米长跑运动.一时间操场上熙熙攘攘,摩肩接踵,盛况空前.为了 ...

  6. BZOJ4998 星球联盟(LCT+双连通分量+并查集)

    即要求动态维护边双.出现环时将路径上的点合并即可.LCT维护.具体地,加边成环时makeroot+access+splay一套把这段路径提出来,暴力dfs修改并查集祖先,并将这部分与根断开,视为删除这 ...

  7. 【BZOJ2049】 [Sdoi2008]Cave 洞穴勘测 LCT/并查集

    两种方法: 1.LCT 第一次LCT,只有link-cut和询问,无限T,到COGS上找了数据,发现splay里的父亲特判出错了(MD纸张),A了,好奇的删了反转T了.... #include < ...

  8. 【BZOJ】2049: [Sdoi2008]Cave 洞穴勘测(lct/并查集)

    http://www.lydsy.com/JudgeOnline/problem.php?id=2049 bzoj挂了..在wikioi提交,,1A-写lct的速度越来越快了-都不用debug-- 新 ...

  9. BZOJ_2049_[Sdoi_2008]_Cave_洞穴勘测_(LCT/并查集)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=2049 给出一个森林,起始互不相连,现在有link和cut两种操作,问x,y是否在一棵树里. 分 ...

随机推荐

  1. 在mac上显示网速的软件——iStat Menus 5:

    在mac上显示网速的软件——iStat Menus 5: https://bjango.com/mac/istatmenus/ 注册码: Email: 982092332@qq.com SN: GAW ...

  2. 十一、Linux 命令大全

    Linux 命令大全 Linux 命令大全 1.文件管理 cat chattr chgrp chmod chown cksum cmp diff diffstat file find git gitv ...

  3. JDK5后的特性整理

    为了大家对JDK有一个全面的了解,下面是我从网上查找并整理了JDK5以后的所有关键新特性!(将会持续更新中) JDK5新特性 自动装箱与拆箱 枚举 静态导入 可变参数(Varargs) 内省(intr ...

  4. 【PHP】Laravel将HTML实体转换回普通字符

    问题 最近一个laravel模板的项目需要用到summernote富文本编辑器,内容保存到数据库里是原始的html代码.再读取出来时使用htmlspecialchars_decode()对内容进行转换 ...

  5. ODBC error in PHP: “No tuples available at this result index”

    ODBC error in PHP: “No tuples available at this result index” 在执行存储过程的时候发生如题的错误,在stackoverflow上找到了相同 ...

  6. Qt之pro文件解析

    在我们创建Qt工程项目时,Qt Creator总会创建一个.pro文件,我们称.pro文件为Qt的工程管理文件.一个工程项目可以包含一个或多个.pro文件.理解和掌握pro文件的用法,将有利于Qt开发 ...

  7. Xshell启动时显示丢失MSVCP110.dll解决方法

    成功安装xshell之后,在运行时却弹出“无法启动此程序,因为计算机中丢失MSVCP110.dll.尝试重新安装该程序以解决此问题”,很多人按照提示重装了还是出现同样的问题,本集教程将具体讲解如何处理 ...

  8. 【Consul】Consul架构-Gossip协议

    Consul使用gossip协议管理成员关系.广播消息到整个集群.详情可参考Serf library,Serf使用到的gossip协议可以参阅"SWIM: Scalable Weakly-c ...

  9. Hibernate-ORM:10.Hibernate中的分页

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 本篇博客讲述Hibernate中的分页 hibernate中的分页其实很好写,它通过操作对象的方式,来进行分页 ...

  10. Putty的设置保存

    用了好几年都不知道这功能, 以前每次在连接时只能手工更改字符为utf-8,当时在想怎么这么弱呢 后来才知道... 1 字符 Translation下  字体Appearance下 颜色Colours下 ...