BZOJ4998 星球联盟(LCT+双连通分量+并查集)
即要求动态维护边双。出现环时将路径上的点合并即可。LCT维护。具体地,加边成环时makeroot+access+splay一套把这段路径提出来,暴力dfs修改并查集祖先,并将这部分与根断开,视为删除这些点,以后就以并查集中的祖先代替这些点。access时更新每个点的父亲。注意由于之前的删点操作,判断是否连通需要另开一个并查集而不能findroot。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 200010
#define lson tree[k].ch[0]
#define rson tree[k].ch[1]
#define lself tree[tree[k].fa].ch[0]
#define rself tree[tree[k].fa].ch[1]
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<''||c>'')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int n,m,q,fa[N],fa2[N],size[N];
struct data{int ch[],fa,rev;
}tree[N];
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
int find2(int x){return fa2[x]==x?x:fa2[x]=find2(fa2[x]);}
void rev(int k){if (k) swap(lson,rson),tree[k].rev^=;}
void down(int k){if (tree[k].rev) rev(lson),rev(rson),tree[k].rev=;}
int whichson(int k){return rself==k;}
bool isroot(int k){return lself!=k&&rself!=k;}
void push(int k){if (!isroot(k)) push(tree[k].fa);down(k);}
void move(int k)
{
int fa=tree[k].fa,gf=tree[fa].fa,p=whichson(k);
if (!isroot(fa)) tree[gf].ch[whichson(fa)]=k;tree[k].fa=gf;
tree[fa].ch[p]=tree[k].ch[!p],tree[tree[k].ch[!p]].fa=fa;
tree[k].ch[!p]=fa,tree[fa].fa=k;
}
void splay(int k)
{
push(k);
while (!isroot(k))
{
int fa=tree[k].fa;
if (!isroot(fa))
if (whichson(fa)^whichson(k)) move(k);
else move(fa);
move(k);
}
}
void access(int k){for (int t=;k;t=k,k=tree[k].fa=find(tree[k].fa)) splay(k),tree[k].ch[]=t;}
void makeroot(int k){access(k),splay(k),rev(k);}
void link(int x,int y){makeroot(x),tree[x].fa=y,fa2[find2(x)]=find2(y);}
void dfs(int k,int x)
{
if (!k) return;
if (find(k)!=x) size[x]+=size[find(k)],fa[find(k)]=x;
dfs(lson,x),dfs(rson,x);
}
void addedge(int x,int y)
{
if (find2(x)!=find2(y)) link(x,y);
else
{
makeroot(x),access(y),splay(y);
dfs(tree[y].ch[],y);tree[y].ch[]=;
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj4998.in","r",stdin);
freopen("bzoj4998.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read(),m=read(),q=read();
for (int i=;i<=n;i++) fa[i]=i,fa2[i]=i,size[i]=;
for (int i=;i<=m;i++)
{
int x=find(read()),y=find(read());
if (x!=y) addedge(x,y);
}
for (int i=;i<=q;i++)
{
int x=find(read()),y=find(read());
if (x!=y) addedge(x,y);
if (find(x)==find(y)) printf("%d\n",size[fa[x]]);
else printf("No\n");
}
return ;
}
BZOJ4998 星球联盟(LCT+双连通分量+并查集)的更多相关文章
- BZOJ 2959: 长跑 [lct 双连通分量 并查集]
2959: 长跑 题意:字词加入边,修改点权,询问两点间走一条路径的最大点权和.不一定是树 不是树
- BZOJ4998星球联盟——LCT+并查集(LCT动态维护边双连通分量)
题目描述 在遥远的S星系中一共有N个星球,编号为1…N.其中的一些星球决定组成联盟,以方便相互间的交流.但是,组成 联盟的首要条件就是交通条件.初始时,在这N个星球间有M条太空隧道.每条太空隧道连接两 ...
- bzoj4998 星球联盟 LCT + 并查集
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4998 题解 根据题意,就是要动态维护点双,求出一个点双的权值和. 所以这道题就是和 bzoj2 ...
- bzoj4998 星球联盟
bzoj4998 星球联盟 原题链接 题解 先按照输入顺序建一棵树(森林),然后用一个并查集维护联盟的关系,对于不是树上的边\(a-b\),就把\(a-lca(a,b),b-lca(a,b)\)全部合 ...
- 【bzoj4998】星球联盟 LCT+并查集
题目描述 在遥远的S星系中一共有N个星球,编号为1…N.其中的一些星球决定组成联盟,以方便相互间的交流.但是,组成联盟的首要条件就是交通条件.初始时,在这N个星球间有M条太空隧道.每条太空隧道连接两个 ...
- bzoj4998: 星球联盟(link-cut-tree)
题面 bzoj 题解 bzoj2959: 长跑的弱化版 产生了环就并查集维护一下 Code #include<bits/stdc++.h> #define LL long long #de ...
- HDU 3749 Financial Crisis (点双连通+并查集)
<题目连接> 题目大意: 给你一个(保证输入无重边,无自环)无向图,然后有下面Q条询问,每条询问为:问你u点与v点之间有几条(除了首尾两点外,其他点不重复)的路径.如果有0条或1条输出0或 ...
- BZOJ 1854: [Scoi2010]游戏 [连通分量 | 并查集 | 二分图匹配]
题意: 有$n \le 10^6$中物品,每种两个权值$\le 10^4$只能选一个,使得选出的所有权值从1递增,最大递增到多少 一开始想了一个奇怪的规定流量网络流+二分答案做法...然而我还不知道怎 ...
- 图-连通分量-DFS-并查集-695. 岛屿的最大面积
2020-03-15 16:41:45 问题描述: 给定一个包含了一些 0 和 1的非空二维数组 grid , 一个 岛屿 是由四个方向 (水平或垂直) 的 1 (代表土地) 构成的组合.你可以假设二 ...
随机推荐
- #333. 【NOIP2017】宝藏
#333. [NOIP2017]宝藏 http://uoj.ac/problem/333 1.错误的$n^42^n$做法: dp[s]表示当前的点集为s,然后从这些点中选一个做起点i,然后枚举边,然后 ...
- BZOJ3174. [TJOI2013]拯救小矮人(dp)
题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=3174 题解 其实此题并不需要那么多YY的部分. 我们考虑若干个小矮人逃出的顺序.若跳出的 ...
- linux、WINDOWS命令行下查找和统计行数
linux : 例子: netstat -an | grep TIME_WAIT | wc -l | 管道符 grep 查找命令 wc 统计命令 windows: 例子: netstat -an | ...
- 用php实现简单的自制计算器
存档: <!DOCTYPE html> <html> <head> <title>PHP实现计算器</title> </head> ...
- JS 中屏幕、浏览器和文档的高度、宽度和距离
1.各种对象 window.screen - 屏幕,window - 窗口,document.documentElement & document.body.parentNode - 文档,d ...
- Sublime Text 2 - Unable to find git.exe 错误
今日打开 Sublime Text 2,随即弹出 Package Control - Unable to find git.exe 错误.如下, 原因:曾经通过 git clone 命令获取过 Sub ...
- node stream流
stream 模块可以通过以下方式使用: const stream = require('stream'); Node.js 中有四种基本的流类型: Writable - 可写入数据的流(例如 f ...
- spring mvc 详细配置
转自: http://www.cnblogs.com/superjt/p/3309255.html 现在主流的Web MVC框架除了Struts这个主力 外,其次就是Spring MVC了,因此这也是 ...
- CSS3实现图片渐入效果
很多网站都有那种图片渐入的效果,如:http://www.mi.com/minote/,这种效果用css3和一些js实现起来特别简单. 拿我之前做的页面来说一下怎么利用css3来实现图片渐入效果. 下 ...
- Bracket Sequences Concatenation Problem括号序列拼接问题(栈+map+思维)
A bracket(括号) sequence is a string containing only characters "(" and ")".A regu ...