题目描述

在遥远的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

提示

BZOJ2959弱化版

如果两个星球属于同一个联盟,那么他们就属于一个点双,用LCT维护点双缩点后的树,用两个并查集分别维护每个点属于哪个点双及点之间连通性,加边时分两种情况讨论即可。具体操作参见BZOJ2959。

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<bitset>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define pr pair<int,int>
#define ll long long
using namespace std;
int g[200010];
int fa[200010];
int f[200010];
int s[200010][2];
int sum[200010];
int st[200010];
int r[200010];
int size[200010];
int n,m,p;
int opt;
int x,y;
int find(int x)
{
if(fa[x]==x)
{
return x;
}
return fa[x]=find(fa[x]);
}
int judge(int x)
{
if(g[x]==x)
{
return x;
}
return g[x]=judge(g[x]);
}
int is_root(int rt)
{
return rt!=s[find(f[rt])][0]&&rt!=s[find(f[rt])][1];
}
int get(int rt)
{
return rt==s[find(f[rt])][1];
}
void pushup(int rt)
{
sum[rt]=sum[s[rt][0]]+sum[s[rt][1]]+size[rt];
}
void pushdown(int rt)
{
if(r[rt])
{
swap(s[rt][0],s[rt][1]);
r[s[rt][0]]^=1;
r[s[rt][1]]^=1;
r[rt]^=1;
}
}
void rotate(int rt)
{
int fa=find(f[rt]);
int anc=find(f[fa]);
int k=get(rt);
if(!is_root(fa))
{
s[anc][get(fa)]=rt;
}
s[fa][k]=s[rt][k^1];
f[s[fa][k]]=fa;
s[rt][k^1]=fa;
f[fa]=rt;
f[rt]=anc;
pushup(fa);
pushup(rt);
}
void splay(int rt)
{
int top=0;
st[++top]=rt;
for(int i=rt;!is_root(i);i=find(f[i]))
{
st[++top]=find(f[i]);
}
for(int i=top;i>=1;i--)
{
pushdown(st[i]);
}
for(int fa;!is_root(rt);rotate(rt))
{
if(!is_root(fa=find(f[rt])))
{
rotate(get(fa)==get(rt)?fa:rt);
}
}
}
void access(int rt)
{
for(int x=0;rt;x=rt,rt=find(f[rt]))
{
splay(rt);
s[rt][1]=x;
pushup(rt);
}
}
void reverse(int rt)
{
access(rt);
splay(rt);
r[rt]^=1;
}
void link(int x,int y)
{
reverse(x);
f[x]=y;
g[g[x]]=g[y];
}
void dfs(int x,int rt)
{
fa[x]=rt;
if(s[x][0])
{
dfs(s[x][0],rt);
}
if(s[x][1])
{
dfs(s[x][1],rt);
}
}
int main()
{
scanf("%d%d%d",&n,&m,&p);
for(int i=1;i<=n;i++)
{
fa[i]=g[i]=i;
size[i]=sum[i]=1;
}
for(int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
int fx=find(x);
int fy=find(y);
if(fx!=fy)
{
if(judge(fx)!=judge(fy))
{
link(fx,fy);
}
else
{
reverse(fx);
access(fy);
splay(fy);
size[fy]=sum[fy];
dfs(fy,fy);
s[fy][0]=0;
}
}
}
for(int i=1;i<=p;i++)
{
scanf("%d%d",&x,&y);
int fx=find(x);
int fy=find(y);
if(fx==fy)
{
reverse(fx);
access(fy);
splay(fy);
printf("%d\n",sum[fx]);
}
else if(judge(fx)!=judge(fy))
{
link(fx,fy);
printf("No\n");
}
else
{
reverse(fx);
access(fy);
splay(fy);
size[fy]=sum[fy];
dfs(fy,fy);
s[fy][0]=0;
printf("%d\n",sum[fy]);
}
}
}

BZOJ4998星球联盟——LCT+并查集(LCT动态维护边双连通分量)的更多相关文章

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

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

  2. BZOJ2959长跑——LCT+并查集(LCT动态维护边双连通分量)

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

  3. BZOJ4229选择——LCT+并查集+离线(LCT动态维护边双连通分量)

    题目描述 现在,我想知道自己是否还有选择. 给定n个点m条边的无向图以及顺序发生的q个事件. 每个事件都属于下面两种之一: 1.删除某一条图上仍存在的边 2.询问是否存在两条边不相交的路径可以从点u出 ...

  4. 【bzoj4998】星球联盟 LCT+并查集

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

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

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

  6. 【loj6038】「雅礼集训 2017 Day5」远行 树的直径+并查集+LCT

    题目描述 给你 $n$ 个点,支持 $m$ 次操作,每次为以下两种:连一条边,保证连完后是一棵树/森林:询问一个点能到达的最远的点与该点的距离.强制在线. $n\le 3\times 10^5$ ,$ ...

  7. bzoj 3669: [Noi2014]魔法森林(并查集+LCT)

    Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N,边标号为1..M.初始时小E同学在号节 ...

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

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

  9. BZOJ 2959 长跑 (LCT+并查集)

    题面:BZOJ传送门 当成有向边做的发现过不去样例,改成无向边就忘了原来的思路.. 因为成环的点一定都能取到,我们把它们压成一个新点,权值为环上所有点的权值和 这样保证了图是一颗森林 每次询问转化为, ...

随机推荐

  1. kubernete 数据库 etcd

    etcdctl --cert-file /etc/ssl/etcd/ssl/member-pserver78.pem --key-file /etc/ssl/etcd/ssl/member-pserv ...

  2. TerraGate软件安装后,不能启动的解决办法

    在服务端安装Skyline的TerraGate软件的时候,大家可能会遇到过这样的问题,“TerraGate软件安装后,不能启动”,很多时候,这个问题是因为TerraGate设 置的端口号已经被占用造成 ...

  3. day86

    视图组件 基于以往我们所用的视图函数,我们发现其中冗余的代码比较多,今天就来对其进行封装,争取做一个代码洁癖者 原来我们的视图函数: class Book(APIView): def get(self ...

  4. 使用HashSet<>去除重复元素的集合

    比如,某一个阵列中,有重复的元素,我们想去除重复的,保留一个.HashSet<T>含不重复项的无序列表,从MSDN网上了解到,这集合基于散列值,插入元素的操作非常快. 你可以写一个方法: ...

  5. Idea Live Template代码片段总结

    目录 Idea Live Template总结 一.演示 二.详细介绍 2.1 类型 2.2设置(win默认快捷键win+alt+s) 2.3 快捷键 2.4 实战 Idea Live Templat ...

  6. Ionic app升级插件开发

    终于走到了写插件的这个地方了,插件的过程: 1.安装plugman插件,管理我们的程序 npm install -g plugman 2.创建插件项目appUpgrade,cd 到你的目标目录下,执行 ...

  7. jQuery checkbox全选 和全部取消

    1.chkAll选中,全部chk选中  ,chkAll取消选中,全部chk取消选中 //chkAll选中,全部chk选中 ,chkAll取消选中,全部chk取消选中 $("#chkAll&q ...

  8. RHEL7基本命令

    Terminal TTY TTY是TeleTYpe的一个老缩写. Teletypes,或者teletypewriters,原来指的是电传打字机,是通过串行线用打印机键盘通过阅读和发送信息的东西,和古老 ...

  9. vsftpd虚拟账户配置

    1. 概述 FTP是文件传输协议,在内外网的文件传输中使用广泛. 本篇博客主要介绍FTP服务器的部署和测试. 2. 软件环境部署 查看系统是否安装FTP软件(vsftpd),执行命令:rpm -qa ...

  10. 做完小程序项目、老板给我加了5k薪资~

    大家好,我是苏南,今天要给大家分享的是最近公司做的一个小程序项目,过程中的一些好的总结和遇到的坑,希望能给其他攻城狮带来些许便利,更希望能做完之后老板给你加薪- 今天是中秋节的第一天,假日的清晨莫名的 ...