新技能 get √ :LCT 维护边双连通分量

这题题意就是动态加边,每次求边的两端是否在一个边双连通分量里,输出 "No" 或者边双连通分量的大小

可以用两个并查集分别记录连通性和双连通性,如果还没连通就是 "No" 并在 LCT 上连边,否则直接把这条链 split 出来查即可

注意 LCT 维护的是双连通分量,所以每次跳 fa 的时候不再是 fa,而是 fa 所在的双连通分量

#include <bits/stdc++.h>
#define LL long long
#define rep(i, s, t) for (register int i = (s), i##end = (t); i <= i##end; ++i)
#define dwn(i, s, t) for (register int i = (s), i##end = (t); i >= i##end; --i)
using namespace std;
inline int read() {
int x = ,f = ; char ch = getchar();
for(; !isdigit(ch); ch = getchar())if(ch == '-') f = -f;
for(; isdigit(ch); ch = getchar())x = * x + ch - '';
return x * f;
}
const int maxn = ;
int par[maxn], par2[maxn], size[maxn], ans;
inline int find(int x) {return x == par[x] ? x : par[x] = find(par[x]);}
inline int find2(int x) {return x == par2[x] ? x : par2[x] = find2(par2[x]);}
int n, m, p;
#define ls ch[x][0]
#define rs ch[x][1]
int ch[maxn][], fa[maxn], rev[maxn], st[maxn], top;
inline int isroot(int x) { return ch[find(fa[x])][] != x && ch[find(fa[x])][] != x; }
inline void pushdown(int x) {
if(rev[x]) {
swap(ls, rs);
if(ls) rev[ls] ^= ;
if(rs) rev[rs] ^= ;
rev[x] = ;
}
}
inline void rotate(int x) {
int y = find(fa[x]), z = find(fa[y]);
int l = (ch[y][] == x), r = l ^ ;
if(!isroot(y)) ch[z][ch[z][] == y] = x;
fa[x] = z; fa[ch[x][r]] = y; fa[y] = x;
ch[y][l] = ch[x][r]; ch[x][r] = y;
}
inline void splay(int x) {
st[top = ] = x;
for(int i=x;!isroot(i);i=find(fa[i])) st[++top] = find(fa[i]);
for(int i=top;i;i--) pushdown(st[i]);
//PUSHDOWN(x);
//cout << x << endl;
while(!isroot(x)) {
int y = find(fa[x]), z = find(fa[y]);
if(!isroot(y)) {
if(ch[z][] == y ^ ch[y][] == x) rotate(x);
else rotate(y);
} rotate(x);
}
}
inline void access(int x) {
for(int y = ; x; splay(x), rs = y, y = x, x = find(fa[x]));
}
inline void makeroot(int x) {
access(x); splay(x); rev[x] ^= ;
}
inline void link(int x, int y) {
makeroot(x); fa[x] = y;
}
void dfs(int x, int pre) {
if(!x) return;
ans += size[x];
if(x != pre) size[pre] += size[x], par[x] = pre;
dfs(ls, pre); dfs(rs, pre);
}
inline void lnk(int u, int v) {
ans = ;
if(find2(u) != find2(v)) {
par2[par2[u]] = par2[v];
//cout << u << " " << v << endl;
link(u, v);
}
else {
makeroot(u); access(v); splay(v); dfs(v, v);
}
}
int main() {
n = read(), m = read(), p = read();
rep(i, , n) size[i] = , par[i] = i, par2[i] = i;
rep(i, , m) {
int u = find(read()), v = find(read());
lnk(u, v);
}
rep(i, , p) {
int u = find(read()), v = find(read()); lnk(u, v);
printf(ans ? "%d\n" : "No\n", ans);
}
}

bzoj 4998 星球联盟的更多相关文章

  1. 【刷题】BZOJ 4998 星球联盟

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

  2. bzoj4998 星球联盟

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

  3. [jzoj]3875.【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)

    Link https://jzoj.net/senior/#main/show/3875 Problem 在遥远的S星系中一共有N个星球,编号为1…N.其中的一些星球决定组成联盟,以方便相互间的交流. ...

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

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

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

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

  6. 【NOIP2017练习&BZOJ4998】星球联盟(强联通分量,并查集)

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

  7. JZOJ 3875 星球联盟

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

  8. 【JZOJ3875】【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)

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

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

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

随机推荐

  1. node第一个程序

    var http = require('http') var url = require('url') var fs=require("fs") var router = requ ...

  2. 高通平台下安卓opencl小例子

    http://blog.csdn.net/wcj0626/article/details/26272019 先到高通的qdn下载adreno GPU SDK,里面有OpenCL的例子.https:// ...

  3. 【Head First Servlets and JSP】笔记2:MVC迷你教程

    1.采用MVC,不仅要求业务逻辑和表示分离.实际上,业务逻辑甚至根本不知道表示的存在.MVC的关键是,业务逻辑要与表示分离,而要求在中间放上别的东西,这样业务逻辑本身就可以作为一个可以重用的Java类 ...

  4. 002. MySQL复制操作

    #### 1.Setting the Replication Master Configuration On a replication master, you must enable binary  ...

  5. java常见异常(更新中)

    Java的异常分为两种,一种是运行时异常(RuntimeException),一种是非运行异常也叫检查式异常(CheckedException) .NullPointerException 空指针异常 ...

  6. 非法字符: '\ufeff' 解决方案|错误: 需要class, interface或enum

    解决方案,把文件用Editplus打开,UTF-8+BOM编码的文件转为普通的UTF-8文件

  7. Mysql导出导入数据库

    1. 导出数据库:mysqldump -u 用户名 -p 数据库名 > 导出的文件名 mysqldump -u root -p database > database.sql 2. 导入数 ...

  8. 网络数据包头部在linux网络协议栈中的变化

    接收时使用skb_pull()不断去掉各层协议头部:发送时使用skb_push()不断添加各层协议头部. 先说说接收: * eth_type_trans - determine the packet' ...

  9. scala mapPartitionsWithIndex函数的使用

    var rdd1=sc.makeRDD(Array((1,"A"),(2,"B"),(3,"C"),(4,"D")),2 ...

  10. Largest Rectangle in Histogram, 求矩形图中最大的长方形面积

    问题描述: Given n non-negative integers representing the histogram's bar height where the width of each ...