Hdu 5458 Stability (LCA + 并查集 + 树状数组 + 缩点)
题目链接:
题目描述:
给出一个还有环和重边的图G,对图G有两种操作:
1 u v, 删除u与v之间的一天边 (保证这个边一定存在)
2 u v, 查询u到v的路径上有几条桥。
解题思路:
这个题目有很多次操作,包含查询和删边两类,首先想到的是连通分量加缩点。如果按照顺序来,删边时候求桥就是问题了。所以可以离线处理,然后一边记录答案一边加边缩点。
对于一个图,把连通分量缩成一个点后,这个图就成为了一棵树, 然后深度差就等于桥的数目。查询的时候对于(u, v)桥的数目等于(设定deep[x]为x的深度,LCA(x, y)为(x, y)的父节点) deep[u] + deep[v] - 2 * deep[LCA(u, v)];
现在问题就成了怎么才能更快的缩点和维护点的深度。
缩点问题:在树上加上一条边就会形成一个环,然后这个环(强连通分量)上点就会被缩成一个点,然后用并查集来维护强联通分量,每次只需要合并父节点(每个点只能被缩一次,复杂度被平摊还是很可观的)。
维护节点深度:每次儿子节点合并到父亲节点的时候,儿子节点的子孙节点的深度都要减一。在这里我们可以用dfs序 + 树状数组来维护节点的深度。利用树状数组的区间更改点查询优化维护深度的操作。
还有最后一个问题就是计算(u, v)节点之间桥数目的时候,需要用到LCA,可以利用树上倍增LCA来优化时间复杂度。
这个题目还是很值得本扎扎练手的,考察了很多东西,真是把压箱底的东西都翻出来晒了晒,仰慕当场ac的聚聚们。
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = ;
const int N = ;
const int M = ; struct node
{
int to, del;
node(int x):to(x),del() {}
bool operator < (const node & a) const
{
if (to != a.to) return to < a.to;
return del > a.del;
}
};
vector <node> vec[maxn]; struct Query
{
int op, u, v;
void read ()
{
scanf ("%d %d %d", &op, &u, &v);
if (op == )
{
lower_bound (vec[u].begin(), vec[u].end(), node(v)) -> del = true;
lower_bound (vec[v].begin(), vec[v].end(), node(u)) -> del = true;
}
}
} query[N]; int n, m, q; void init ()
{
for (int i=; i<=n; i++)
vec[i].clear();
} struct bit_tree
{
int tree[maxn]; void init()
{
memset (tree, , sizeof(tree));
} int lowbit (int x)
{
return x & (-x);
} void change (int x, int num)
{
while (x <= n)
{
tree[x] += num;
x += lowbit (x);
}
} void update (int x, int y, int num)
{
change (x, num);
change (y+, -num);
} int query (int x)
{
int res = ;
while (x)
{
res += tree[x];
x -= lowbit (x);
}
return res;
} }Bit_tree; int begin_id[maxn], end_id[maxn], deep[maxn], ntime;
int fa[maxn][M];
void dfs (int u, int father, int dep)
{
if (father > )
vec[u].erase (lower_bound(vec[u].begin(), vec[u].end(), node(father))); fa[u][] = father;
begin_id[u] = ++ntime;
deep[u] = dep; for (int i=; i<vec[u].size(); i++)
{
node p = vec[u][i];
if (p.del || begin_id[p.to]) continue;
vec[u][i].del = true;
dfs (p.to, u, dep+);
} end_id[u] = ntime;
Bit_tree.update (begin_id[u], end_id[u], );
} struct Lca
{
void init ()
{
for (int i=; i<M; i++)
for (int j=; j<=n; j++)
fa[j][i] = fa[fa[j][i-]][i-];
} int lca (int u, int v)
{
if (deep[u] < deep[v]) swap (u, v);
int num = deep[u] - deep[v];
for (int i=; i<M; i++)
if ((<<i) & num) u = fa[u][i];
if (u == v) return u;
for (int i=M-; i>=; i--)
if (fa[u][i] != fa[v][i])
{
u = fa[u][i];
v = fa[v][i];
}
return fa[u][];
} }LCA; int father[maxn];
struct UNion
{
void init()
{
for (int i=; i<=n; i++)
father[i] = i;
} int find (int x)
{
if (x != father[x]) father[x] = find (father[x]);
return father[x];
} void merge_fa (int x, int y)
{
x = find (x);
while (x != y)
{
int t = find(fa[x][]);
father[x] = t;
Bit_tree.update(begin_id[x], end_id[x], -);
x = t;
}
} void merge (int x, int y)
{
int l = find (LCA.lca (x, y));
merge_fa (x, l);
merge_fa (y, l);
} }Union; int ans[N], res;
void solve ()
{
Bit_tree.init ();
ntime = res = ;
memset (begin_id, , sizeof(begin_id));
dfs (, , );
LCA.init ();
Union.init(); for (int i=; i<=n; i++)
{
for (int j=; j<vec[i].size(); j++)
{
node p = vec[i][j];
if (p.del) continue;
Union.merge (p.to, i);
}
} for (int i=q; i>; i--)
{
Query p = query[i];
int u = begin_id[p.u];
int v = begin_id[p.v];
int x = begin_id[LCA.lca(p.u, p.v)];
if (p.op == )
Union.merge(p.u, p.v);
else
ans[++ res] = Bit_tree.query(u) + Bit_tree.query(v) - *Bit_tree.query(x);
} while(res)
printf ("%d\n", ans[res --]);
} int main ()
{
int t, u, v;
scanf ("%d", &t); for (int i=; i<=t; i++)
{
scanf("%d %d %d", &n, &m, &q);
init (); for (int j=; j<m; j++)
{
scanf ("%d %d", &u, &v);
vec[u].push_back (node(v));
vec[v].push_back (node(u));
} for (int j=; j<=n; j++)
sort (vec[j].begin(), vec[j].end()); for (int j=; j<=q; j++)
query[j].read(); printf ("Case #%d:\n", i);
solve (); }
return ;
}
Hdu 5458 Stability (LCA + 并查集 + 树状数组 + 缩点)的更多相关文章
- hdu 6200 mustedge mustedge(并查集+树状数组 或者 LCT 缩点)
hdu 6200 mustedge mustedge(并查集+树状数组 或者 LCT 缩点) 题意: 给一张无向连通图,有两种操作 1 u v 加一条边(u,v) 2 u v 计算u到v路径上桥的个数 ...
- HDU 5458 Stability(双连通分量+LCA+并查集+树状数组)(2015 ACM/ICPC Asia Regional Shenyang Online)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5458 Problem Description Given an undirected connecte ...
- BZOJ-3211花神游历各国 并查集+树状数组
一开始想写线段树区间开方,简单暴力下,但觉得变成复杂度稍高,懒惰了,编了个复杂度简单的 3211: 花神游历各国 Time Limit: 5 Sec Memory Limit: 128 MB Subm ...
- BZOJ3211 花神游历各国 并查集 树状数组
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3211 题意概括 有n个数形成一个序列. m次操作. 有两种,分别是: 1. 区间开根(取整) 2. ...
- 【bzoj4869】[Shoi2017]相逢是问候 扩展欧拉定理+并查集+树状数组
题目描述 Informatik verbindet dich und mich. 信息将你我连结. B君希望以维护一个长度为n的数组,这个数组的下标为从1到n的正整数.一共有m个操作,可以分为两种:0 ...
- HDU 4750 Count The Pairs ★(图+并查集+树状数组)
题意 给定一个无向图(N<=10000, E<=500000),定义f[s,t]表示从s到t经过的每条路径中最长的边的最小值.Q个询问,每个询问一个t,问有多少对(s, t)使得f[s, ...
- la4730(并查集+树状数组)
https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=30& ...
- 【BZOJ3211】花神游历各国 并查集+树状数组
[BZOJ3211]花神游历各国 Description Input Output 每次x=1时,每行一个整数,表示这次旅行的开心度 Sample Input 41 100 5 551 1 22 1 ...
- 【BZOJ4382】[POI2015]Podział naszyjnika 堆+并查集+树状数组
[BZOJ4382][POI2015]Podział naszyjnika Description 长度为n的一串项链,每颗珠子是k种颜色之一. 第i颗与第i-1,i+1颗珠子相邻,第n颗与第1颗也相 ...
随机推荐
- 豆瓣面试题strstr)
/*(豆瓣2013面试题strstr) 有一个在给定字符串中查找子串的函数strstr, 该函数从给定的字符串src中查找substr并返回一个整数, 指明substr第一次出现的位置(从0开始计数) ...
- 嵌入式驱动开发之2440/2410---uboot 移植
http://blog.chinaunix.net/uid-20620288-id-3058904.html
- Java实现HttpClient发送GET、POST请求(https、http)
1.引入相关依赖包 jar包下载:httpcore4.5.5.jar fastjson-1.2.47.jar maven: <dependency> <groupId>o ...
- 3144: [Hnoi2013]切糕
3144: [Hnoi2013]切糕 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1526 Solved: 827[Submit][Status] ...
- nginx搭建支持http和rtmp协议的流媒体server之中的一个
实验目的:让Nginx支持flv和mp4格式文件,支持RTMP协议的直播和点播:同一时候打开RTMP的HLS功能 资料:HTTP Live Streaming(缩写是 HLS)是一个由苹果公司提出的 ...
- iOS 开发用到的常用工具
如果你去到一位熟练的木匠的工作室,你总是能发现他/她有一堆工具来完成不同的任务. 软件开发同样如此.你可以从软件开发者如何使用工具中看出他水准如何.有经验的开发者精于使用工具.对你目前所使用的工具不断 ...
- pod导入第三方库头文件不能自动联想的解决方法
使用了一段时间CocoaPods来管理Objective-c的类库,方便了不少.但是有一个小问题,当我在xcode输入import关键字的时候,没有自动联想补齐代码的功能,需要手工敲全了文件名,难以适 ...
- 一个基本的spring+mybatis所需要的包
spring+mybatis需要的包:org.springframework.spring-webmvc(spring框架DispatcherServlet需要,spring-webmvc会依赖spr ...
- mmwave
毫米波(mmWave) 致力于支持5G应用创新开发,集成在BEEcube BEE7基带平台上的赛灵思256QAM毫米波调制解调器IP为宽带回程原型设计提供完整的开箱即用型解决方案 赛灵思公司 (NAS ...
- 计算机科学 —— 时间戳(timestamp)
时间戳的一个重要属性即是:唯一性,以起到唯一标识的作用: 1. linux 命令行 $ date +%s 1506222745 2. Python 时间戳 内置 time 库 >> tim ...