BCC.cpp 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. //Find the biconnected component in the undirected graph.
  2. //It means that, for all (x,y), there are at least two ways from u to y using the different nodes.
  3. //Remark: every edge belongs to the one of the bcc.
  4. // two different bcc may have au most one common node (the cut vertex)
  5. //
  6. //For the edge-bcc :
  7. // delete all the bridges, every cc is a bcc in the original graph.
  8. int pre[maxn], iscut[maxn], bccno[maxn], dfs_clock, bcc_cnt;
  9. vector<int> G[maxn], bcc[maxn];
  10. struct Edge{
  11. int u, v;
  12. Edge(int uu, int vv): u(uu), v(vv) {}
  13. };
  14. stack<Edge> S;
  15. int dfs(int u, int fa) {
  16. int lowu = pre[u] = ++dfs_clock;
  17. int child = 0;
  18. for (int i = 0; i < G[u].size(); i++){
  19. int v = G[u][i];
  20. Edge e = (Edge){u, v};
  21. if (!pre[v]) {
  22. S.push(e);
  23. child ++;
  24. int lowv = dfs(v, u);
  25. lowu = min(lowu, lowv);
  26. if (lowv >= pre[u]) {
  27. iscut[u] = true;
  28. bcc_cnt++; bcc[bcc_cnt].clear();
  29. for (;;){
  30. Edge x = S.top(); S.pop();
  31. if (bccno[x.u] != bcc_cnt) {
  32. bcc[bcc_cnt].push_back(x.u);
  33. bccno[x.u] = bcc_cnt;
  34. }
  35. if (bccno[x.v] != bcc_cnt) {
  36. bcc[bcc_cnt].push_back(x.v);
  37. bccno[x.v] = bcc_cnt;
  38. }
  39. if (x.u == u && x.v == v) break;
  40. }
  41. }
  42. }
  43. else if (pre[v] < pre[u] && v != fa){
  44. S.push(e);
  45. lowu = min(lowu, pre[v]);
  46. }
  47. }
  48. if (fa < 0 && child == 1) iscut[u] = 0;
  49. return lowu;
  50. }
  51. void find_bcc(int n) {
  52. memset(pre, 0, sizoef(pre));
  53. memset(iscut, 0, sizeof(iscut));
  54. memset(bccno, 0, sizoef(bccno));
  55. dfs_clock = bcc_cnt = 0;
  56. for (int i = 0; i < n; i++)
  57. if (!pre[i]) dfs(i, -1);
  58. }