BZOJ4998星球联盟——LCT+并查集(LCT动态维护边双连通分量)
题目描述
输入
输出
样例输入
1 2
4 3
4 5
2 3
1 3
4 5
2 4
样例输出
3
2
5
提示
.png)
如果两个星球属于同一个联盟,那么他们就属于一个点双,用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动态维护边双连通分量)的更多相关文章
- 【bzoj4998】星球联盟(并查集+边双)
题面 传送门 题解 总算有自己的\(bzoj\)账号啦! 话说这题好像\(Scape\)去年暑假就讲过--然而我到现在才会-- \(LCT\)什么的跑得太慢了而且我也不会,所以这里是一个并查集的做法 ...
- BZOJ2959长跑——LCT+并查集(LCT动态维护边双连通分量)
题目描述 某校开展了同学们喜闻乐见的阳光长跑活动.为了能“为祖国健康工作五十年”,同学们纷纷离开寝室,离开教室,离开实验室,到操场参加3000米长跑运动.一时间操场上熙熙攘攘,摩肩接踵,盛况空前. 为 ...
- BZOJ4229选择——LCT+并查集+离线(LCT动态维护边双连通分量)
题目描述 现在,我想知道自己是否还有选择. 给定n个点m条边的无向图以及顺序发生的q个事件. 每个事件都属于下面两种之一: 1.删除某一条图上仍存在的边 2.询问是否存在两条边不相交的路径可以从点u出 ...
- 【bzoj4998】星球联盟 LCT+并查集
题目描述 在遥远的S星系中一共有N个星球,编号为1…N.其中的一些星球决定组成联盟,以方便相互间的交流.但是,组成联盟的首要条件就是交通条件.初始时,在这N个星球间有M条太空隧道.每条太空隧道连接两个 ...
- bzoj4998 星球联盟 LCT + 并查集
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4998 题解 根据题意,就是要动态维护点双,求出一个点双的权值和. 所以这道题就是和 bzoj2 ...
- 【loj6038】「雅礼集训 2017 Day5」远行 树的直径+并查集+LCT
题目描述 给你 $n$ 个点,支持 $m$ 次操作,每次为以下两种:连一条边,保证连完后是一棵树/森林:询问一个点能到达的最远的点与该点的距离.强制在线. $n\le 3\times 10^5$ ,$ ...
- bzoj 3669: [Noi2014]魔法森林(并查集+LCT)
Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N,边标号为1..M.初始时小E同学在号节 ...
- 【bzoj2959】长跑 LCT+并查集
题目描述 某校开展了同学们喜闻乐见的阳光长跑活动.为了能“为祖国健康工作五十年”,同学们纷纷离开寝室,离开教室,离开实验室,到操场参加3000米长跑运动.一时间操场上熙熙攘攘,摩肩接踵,盛况空前.为了 ...
- BZOJ 2959 长跑 (LCT+并查集)
题面:BZOJ传送门 当成有向边做的发现过不去样例,改成无向边就忘了原来的思路.. 因为成环的点一定都能取到,我们把它们压成一个新点,权值为环上所有点的权值和 这样保证了图是一颗森林 每次询问转化为, ...
随机推荐
- MySQL 基础八 用户管理
SELECT * FROM student INSERT INTO student(NAME,sex,createuser,createtime) VALUES('jack','男','ligenyu ...
- xhtml和html的区别 html5和xhtml的区别
xhtml和html的区别 - 分为两大类比较:一个是功能上的差别,另外是书写习惯的差别.关于功能上的差别,主要是XHTML可兼容各大浏览器.手机以及PDA,并且浏览器也能快速正确地编译网页,- XH ...
- C#深入理解AutoResetEvent和ManualResetEvent
当在C#使用多线程时就免不了使用AutoResetEvent和ManualResetEvent类,可以理解这两个类可以通过设置信号来让线程停下来或让线程重新启动,其实与操作系统里的信号量很相似(汗,考 ...
- Python从菜鸟到高手(3):声明变量
变量(variable)是Python语言中一个非常重要的概念.变量的主要作用就是为Python程序中的某个值起一个名字.类似于"张三"."李四"." ...
- JVM规范系列第3章:为Java虚拟机编译
Oracle 的 JDK 包括两部分内容:一部分是将 Java 源代码编译成 Java 虚拟机的指令集的编译器,另一部分是用于Java 虚拟机的运行时环境. 第一部分应该说的是 Javac 这个前置编 ...
- windows平台下编辑的内容传到linux平台出现中文乱码的解决办法
现象说明:在windows下编辑的内容,上传到linux平台下出现中文乱码.如下: 在windows平台编写haha.txt文件,内容如下: 上传到linux平台,出现中文乱码,如下: 基本上面出现的 ...
- BUAAMOOC项目M2 postmortem
设想和目标 1.我们的软件要解决什么问题?是否定义的很清楚?是否对典型用户和典型场景有清晰的描述? 我们的软件是基于北航MOOC网站做的Android手机客户端,用于便捷的在学校里通过手机做到随时随地 ...
- 【Beta阶段】第九次Scrum Meeting!(论坛已成功上线)
每日任务内容: 本次会议为第九次Scrum Meeting会议~ 本次会议为团队项目第九次会议,在会议前大家取得了重大成果! 队员 昨日完成任务 明日要完成任务 刘乾 #179 完成1021的数据处理 ...
- linux第三次读书笔记
第七章:链接 一.编译器驱动程序 编译系统提供的调用预处理器.编译器.汇编器和链接器来构造目标文件的程序. 二.静态链接 三.目标文件 三种形式: 1.可重定位目标文件: 2.可执行目标文件: 3.共 ...
- 《Linux内核分析》第八周:进程的切换和系统的一般执行过程
杨舒雯(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 实验目的: 使用gdb ...