题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5458

Problem Description
Given an undirected connected graph G with n nodes and m edges, with possibly repeated edges and/or loops. The stability of connectedness between node u and node v is defined by the number of edges in this graph which determines the connectedness between them (once we delete this edge, node u and v would be disconnected).

You need to maintain the graph G, support the deletions of edges (though we guarantee the graph would always be connected), and answer the query of stability for two given nodes.

 
Input
There are multiple test cases(no more than 3 cases), and the first line contains an integer t, meaning the totally number of test cases.

For each test case, the first line contains three integers n, m and q, where 1≤n≤3×104,1≤m≤105 and 1≤q≤105. The nodes in graph G are labelled from 1 to n.

Each of the following m lines contains two integers u and v describing an undirected edge between node u and node v.

Following q lines - each line describes an operation or a query in the formats:
⋅ 1 a b: delete one edge between a and b. We guarantee the existence of such edge.
⋅ 2 a b: query the stability between a and b.

 
Output
For each test case, you should print first the identifier of the test case.

Then for each query, print one line containing the stability between corresponding pair of nodes.

题目大意:给一个N个点M条边的无向图,有Q个询问:1、删掉a、b之间所存在的边;2、询问有多少条边,单独删掉之后a与b不再连通。

思路:脑洞大开。

对于询问,首先想到的就是a与b之间有多少桥(割边),然后想到双连通分量,然而删边是个坑爹的问题,于是我们离线倒着来,把删边变成加边。

双连通分量这种东西呢,其实缩点连起来之后,就是一棵树辣。

然后询问两个点的时候,设根到点x的距离为dep[x],a、b的最近公共祖先为lca(a, b),那么询问query(a, b) = dep[a] + dep[b] - 2 * dep[lca(a, b)]

加一条边的时候呢,比如加edge(a, b),那么原来的a到b的路径就形成了一个环,那么这个环就应该缩成一个双连通分量(每个点只会被缩一次,平摊的复杂度肯定是没问题的)。

这里可以用并查集来维护同一个双连通分量,每次都是儿子合并到父亲,然后每一次点u合并到父亲的时候,u和u的所有子孙的高度都会减一。

因为要处理一棵子树的所有值,这里使用DFS序+树状数组的方法来维护每个点的深度dep。

然后求LCA这里用的是树上倍增。整个题目要做的就是这些了。

然后整个流程就是:

1、初始化边表并读入所有数据并给边表排序用于查找(我这里用了vector)。(复杂度O(n+m+q+mlog(m)))

2、然后给1操作涉及的边打个删除标记。(复杂度O(qlog(m)))

3、DFS随便建一棵树,给DFS到的边打个删除标记(我直接把父边从vector移除了),顺便建立好DFS序和树状数组、dep和fa数组(用于LCA倍增)。(复杂度O(n+m+nlog(n)))

4、初始化LCA倍增。(复杂度O(nlog(n)))

5、对于每条没打标记的边(即树里的横向边?) edge(a, b),合并路径path(a, b)上的所有点,并维护好树状数组。(复杂度为O(m+nlog(n)))

6、逆序跑询问,第一个操作就加边,加边方法同流程4,第二个操作便是求出LCA,然后用树状数组扒出每个点的深度,然后加加减减得到结果并存起来。(复杂度O(qlog(n)+nlog(n))))

7、输出结果。(复杂度O(q))

代码(889MS):

  1. #include <cstdio>
  2. #include <algorithm>
  3. #include <iostream>
  4. #include <cstring>
  5. #include <vector>
  6. #include <cctype>
  7. using namespace std;
  8. typedef long long LL;
  9.  
  10. const int MAXV = ;
  11. const int MAXQ = ;
  12. const int MAX_LOG = ;
  13. const int INF = 0x3f3f3f3f;
  14. const int MOD = 1e9 + ;
  15.  
  16. int readint() {
  17. char c = getchar();
  18. while(!isdigit(c)) c = getchar();
  19. int res = ;
  20. while(isdigit(c)) res = res * + c - '', c = getchar();
  21. return res;
  22. }
  23.  
  24. struct Node {
  25. int to, del;
  26. Node(int to): to(to), del() {}
  27. bool operator < (const Node &rhs) const {
  28. if(to != rhs.to) return to < rhs.to;
  29. return del > rhs.del;
  30. }
  31. };
  32. vector<Node> adjs[MAXV];
  33. int n, m, q, T;
  34.  
  35. void init() {
  36. for(int i = ; i <= n; ++i) {
  37. adjs[i].clear();
  38. }
  39. }
  40.  
  41. void add_edge(int u, int v) {
  42. adjs[u].push_back(Node(v));
  43. adjs[v].push_back(Node(u));
  44. }
  45.  
  46. struct Query {
  47. int op, a, b, apos, bpos;
  48. void read() {
  49. scanf("%d%d%d", &op, &a, &b);
  50. if(op == ) {
  51. lower_bound(adjs[a].begin(), adjs[a].end(), Node(b))->del = true;
  52. lower_bound(adjs[b].begin(), adjs[b].end(), Node(a))->del = true;
  53. }
  54. }
  55. } query[MAXQ];
  56. int ans[MAXQ], acnt;
  57.  
  58. struct BIT {
  59. int tree[MAXV];
  60. void init() {
  61. memset(tree + , , n * sizeof(int));
  62. }
  63. int lowbit(int x) {
  64. return x & -x;
  65. }
  66. void modify(int x, int val) {
  67. while(x <= n) {
  68. tree[x] += val;
  69. x += lowbit(x);
  70. }
  71. }
  72. void modify(int a, int b, int val) {
  73. modify(a, val);
  74. modify(b + , -val);
  75. }
  76. int get_val(int x) {
  77. int res = ;
  78. while(x) {
  79. res += tree[x];
  80. x -= lowbit(x);
  81. }
  82. return res;
  83. }
  84. } bitree;
  85.  
  86. int bid[MAXV], eid[MAXV], dep[MAXV];
  87. int fa[MAX_LOG][MAXV];
  88. int dfs_clock;
  89.  
  90. void dfs_id(int u, int f, int depth) {
  91. if(f > ) adjs[u].erase(lower_bound(adjs[u].begin(), adjs[u].end(), Node(f)));
  92. fa[][u] = f;
  93. dep[u] = depth;
  94. bid[u] = ++dfs_clock;
  95. for(Node& p : adjs[u]) if(!p.del && !bid[p.to]) {
  96. p.del = ;
  97. dfs_id(p.to, u, depth + );
  98. }
  99. eid[u] = dfs_clock;
  100. bitree.modify(bid[u], eid[u], );
  101. }
  102. void bit_init() {
  103. memset(bid + , , n * sizeof(int));
  104. bitree.init();
  105. dfs_clock = ;
  106. dfs_id(, , );
  107. }
  108.  
  109. struct LCA {
  110. void init_lca() {
  111. for(int k = ; k + < MAX_LOG; ++k) {
  112. for(int u = ; u <= n; ++u) {
  113. if(fa[k][u] == -) fa[k + ][u] = -;
  114. else fa[k + ][u] = fa[k][fa[k][u]];
  115. }
  116. }
  117. }
  118.  
  119. int ask(int u, int v) {
  120. if(dep[u] < dep[v]) swap(u, v);
  121. for(int k = ; k < MAX_LOG; ++k) {
  122. if((dep[u] - dep[v]) & ( << k)) u = fa[k][u];
  123. }
  124. if(u == v) return u;
  125. for(int k = MAX_LOG - ; k >= ; --k) {
  126. if(fa[k][u] != fa[k][v])
  127. u = fa[k][u], v = fa[k][v];
  128. }
  129. return fa[][u];
  130. }
  131. } lca;
  132.  
  133. int dsu[MAXV];
  134.  
  135. int find_set(int x) {
  136. return dsu[x] == x ? x : dsu[x] = find_set(dsu[x]);
  137. }
  138.  
  139. void mergeFa(int u, int gold) {
  140. u = find_set(u);
  141. while(u != gold) {
  142. int t = find_set(fa[][u]);
  143. dsu[u] = t;
  144. bitree.modify(bid[u], eid[u], -);
  145. u = t;
  146. }
  147. }
  148.  
  149. void merge(int u, int v) {
  150. int l = find_set(lca.ask(u, v));
  151. mergeFa(u, l);
  152. mergeFa(v, l);
  153. }
  154.  
  155. void init_tree() {
  156. for(int i = ; i <= n; ++i)
  157. dsu[i] = i;
  158. for(int u = ; u <= n; ++u)
  159. for(Node p : adjs[u]) if(!p.del) {
  160. merge(u, p.to);
  161. }
  162. }
  163.  
  164. void solve() {
  165. bit_init();
  166. lca.init_lca();
  167. init_tree();
  168. for(int i = q - ; i >= ; --i) {
  169. if(query[i].op == ) {
  170. merge(query[i].a, query[i].b);
  171. } else {
  172. int l = lca.ask(query[i].a, query[i].b);
  173. ans[acnt++] = bitree.get_val(bid[query[i].a]) + bitree.get_val(bid[query[i].b]) - * bitree.get_val(bid[l]);
  174. }
  175. }
  176. for(int i = acnt - ; i >= ; --i)
  177. printf("%d\n", ans[i]);
  178. }
  179.  
  180. int main() {
  181. scanf("%d", &T);
  182. for(int t = ; t <= T; ++t) {
  183. scanf("%d%d%d", &n, &m, &q);
  184. init();
  185. for(int i = , u, v; i < m; ++i) {
  186. u = readint(), v = readint();
  187. add_edge(u, v);
  188. }
  189. for(int i = ; i <= n; ++i)
  190. sort(adjs[i].begin(), adjs[i].end());
  191.  
  192. acnt = ;
  193. for(int i = ; i < q; ++i)
  194. query[i].read();
  195.  
  196. printf("Case #%d:\n", t);
  197. solve();
  198. }
  199. }

HDU 5458 Stability(双连通分量+LCA+并查集+树状数组)(2015 ACM/ICPC Asia Regional Shenyang Online)的更多相关文章

  1. Hdu 5458 Stability (LCA + 并查集 + 树状数组 + 缩点)

    题目链接: Hdu 5458 Stability 题目描述: 给出一个还有环和重边的图G,对图G有两种操作: 1 u v, 删除u与v之间的一天边 (保证这个边一定存在) 2 u v, 查询u到v的路 ...

  2. HDU 4750 Count The Pairs ★(图+并查集+树状数组)

    题意 给定一个无向图(N<=10000, E<=500000),定义f[s,t]表示从s到t经过的每条路径中最长的边的最小值.Q个询问,每个询问一个t,问有多少对(s, t)使得f[s, ...

  3. Hdu 5452 Minimum Cut (2015 ACM/ICPC Asia Regional Shenyang Online) dfs + LCA

    题目链接: Hdu 5452 Minimum Cut 题目描述: 有一棵生成树,有n个点,给出m-n+1条边,截断一条生成树上的边后,再截断至少多少条边才能使图不连通, 问截断总边数? 解题思路: 因 ...

  4. (字符串处理)Fang Fang -- hdu -- 5455 (2015 ACM/ICPC Asia Regional Shenyang Online)

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=5455 Fang Fang Time Limit: 1500/1000 MS (Java/Others)  ...

  5. HDU 4729 An Easy Problem for Elfness(主席树)(2013 ACM/ICPC Asia Regional Chengdu Online)

    Problem Description Pfctgeorge is totally a tall rich and handsome guy. He plans to build a huge wat ...

  6. Hdu 5451 Best Solver (2015 ACM/ICPC Asia Regional Shenyang Online) 暴力找循环节 + 递推

    题目链接: Hdu  5451  Best Solver 题目描述: 对于,给出x和mod,求y向下取整后取余mod的值为多少? 解题思路: x的取值为[1, 232],看到这个指数,我的心情是异常崩 ...

  7. Hdu 5459 Jesus Is Here (2015 ACM/ICPC Asia Regional Shenyang Online) 递推

    题目链接: Hdu 5459 Jesus Is Here 题目描述: s1 = 'c', s2 = 'ff', s3 = s1 + s2; 问sn里面所有的字符c的距离是多少? 解题思路: 直觉告诉我 ...

  8. HDU 4719 Oh My Holy FFF(DP+线段树)(2013 ACM/ICPC Asia Regional Online ―― Warmup2)

    Description N soldiers from the famous "*FFF* army" is standing in a line, from left to ri ...

  9. hdu 6200 mustedge mustedge(并查集+树状数组 或者 LCT 缩点)

    hdu 6200 mustedge mustedge(并查集+树状数组 或者 LCT 缩点) 题意: 给一张无向连通图,有两种操作 1 u v 加一条边(u,v) 2 u v 计算u到v路径上桥的个数 ...

随机推荐

  1. C# 读取 CSV 文件

    最近做一个C#项目要导入CSV文件中的数据到Oracle中,使用Aspose.Cells读取中文字段标题却乱码,表的最后多出几行null记录,而且不是免费的,后来找到了NPOI,顾名思义,就是POI的 ...

  2. 【原】PHP初体验

    1. 相关内容介绍 1>互联网开发 互联网:传统互联网.移动互联网 互联网开发:前端开发(前台).后台开发(后端.服务端) 前端开发:视觉展示(用户界面).用户交互.采集输入信息 后台开发:管理 ...

  3. 【JAVA】JDK-SimpleDataFormat 线程不安全!

    [问题] publicclassProveNotSafe { staticSimpleDateFormat df = newSimpleDateFormat("dd-MMM-yyyy&quo ...

  4. ZeroMQ接口函数之 :zmq_msg_size - 以字节为单位返回消息内容的大小

    ZeroMQ 官方地址 :http://api.zeromq.org/4-2:zmq_msg_size zmq_msg_size(3)  ØMQ Manual - ØMQ/3.2.5 Name zmq ...

  5. java比较两个对象是否相等的方法

    java比较两个对象是否相等直接使用equals方法进行判断肯定是不会相同的. 例如: Person  person1  =new Person("张三"); Person  pe ...

  6. ANDROID开发实用小工具

    分享一些 Android开发中的实用小工具,你有发现好工具吗? 来这里分享一下呗 一.find bugs 静态检查工具 http://findbugs.sourceforge.net/ FindBug ...

  7. XmlUtils.java

    package com.vcredit.framework.utils; import java.io.Writer; import org.apache.commons.lang3.StringUt ...

  8. c++聪聪看书(满分代码)

    聪聪是一个善良可爱.睿智聪慧的好孩子.聪聪喜欢看书,这一天她在看一本书时看到了这样一个问题:给你一个正整数n,你要将它分成若干个自然数Ai的和的形式,并且使得这若干个自然数Ai的乘积尽量大,并输出最大 ...

  9. 判断是否为IE浏览器

    function isIE(){        if (!!window.ActiveXObject || "ActiveXObject" in window){          ...

  10. MongoDB的配置、启动、关闭

    MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写.旨在为 WEB 应用提供可扩展的高性能数据存储解决方案. MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系 ...