Advertisement
RedHotChiliPepper

Компоненты двусвязности, мосты, точки сочленения в неор графе без кратных ребер и петлей

Apr 21st, 2021 (edited)
457
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.38 KB | None | 0 0
  1. // Неориентированный граф, не содержащий точек сочленения, называется двусвязным
  2. // Компонента двусвязности <=> какое-то кол-во реберно пересекающихся циклов
  3. // Дерево обхода будет содержать только обратные ребра(помимо ребер дерева)
  4. // Если (v,to) обратное ребро - при помощи снма мерджим все ребра на пути от v до to(пропуская уже смердженные)
  5.  
  6. // чтобы получить мосты берем компоненты из 1 ребра
  7.  
  8. // чтобы получить точки сочленения берем все вершины лежащие как минимум в 2 компонентах
  9.  
  10. const ll N = 2e5 + 100;
  11. ll p[N], sz[N], top[N], h[N];
  12.  
  13. ll get(ll v) {
  14.     if (p[v] == v)
  15.         return v;
  16.     return (p[v] = get(p[v]));
  17. }
  18.  
  19. void merge(ll a, ll b) {
  20.     a = get(a);
  21.     b = get(b);
  22.     if (a == b)return;
  23.     if (sz[a] < sz[b])swap(a, b);
  24.  
  25.     if (h[top[b]] < h[top[a]])
  26.         top[a] = top[b];
  27.     p[b] = a;
  28.     sz[a] += sz[b];
  29. }
  30.  
  31. vector<prll> g[N];
  32. ll used[N], p_ed[N];
  33. prll edges[N];
  34. ll n, m;
  35.  
  36. void dfs(ll v) {
  37.     used[v] = 1;
  38.     for (auto& el : g[v]) {
  39.         ll to = el.first;
  40.         ll id = el.second;
  41.         if (used[to]) { // обратное ребро
  42.             if ((h[v] - h[to]) <= 1)continue; // ребро в прямого предка <=> нет проверки
  43.             assert(sz[id] == 1);
  44.             top[id] = v; // подходит любая с >=h[v]
  45.             ll cur = v;
  46.             while (h[cur] > h[to]) { // мерджим ребра
  47.                 merge(id, p_ed[cur]);
  48.                 cur = top[get(id)];
  49.             }
  50.         }
  51.         else {
  52.             p_ed[to] = id;
  53.             assert(sz[id] == 1);
  54.             top[id] = v;
  55.             h[to] = h[v] + 1;
  56.             dfs(to);
  57.         }
  58.     }
  59. }
  60.  
  61. vector<ll> ans[N];
  62.  
  63. void $main()
  64. {
  65.     cin >> n >> m;
  66.     for (ll i = 0; i < m; ++i) {
  67.         ll v, u; cin >> v >> u;
  68.         --v; --u;
  69.         g[v].emplace_back(u, i);
  70.         g[u].emplace_back(v, i);
  71.         edges[i] = m_p(v, u);
  72.  
  73.         sz[i] = 1;
  74.         p[i] = i;
  75.     }
  76.     for (ll i = 0; i < n; ++i)
  77.         if (!used[i])
  78.             p_ed[i] = -1, dfs(i);
  79.  
  80.     for (ll i = 0; i < m; ++i)
  81.         ans[get(i)].push_back(i);
  82.  
  83.     // Компоненты двусвязности
  84.     /*ll sz_ans = 0;
  85.     for (ll i = 0; i < m; ++i)
  86.         sz_ans += !ans[i].empty();
  87.  
  88.     cout << sz_ans << '\n';
  89.     for (ll i = 0; i < m; ++i) {
  90.         if (ans[i].empty())continue;
  91.         assert(sz[i] == (ll)ans[i].size());
  92.         cout << sz[i] << '\n';
  93.         for (ll id : ans[i])
  94.             cout << edges[id].first + 1 << " " << edges[id].second + 1 << '\n';
  95.     }*/
  96.  
  97.     // Мосты
  98.     /*ll sz_ans = 0;
  99.     for (ll i = 0; i < m; ++i)
  100.         sz_ans += ((ll)ans[i].size() == 1);
  101.  
  102.     cout << sz_ans << '\n';
  103.     for (ll i = 0; i < m; ++i) {
  104.         if ((ll)ans[i].size() != 1)continue;
  105.         for (ll id : ans[i])
  106.             cout << id + 1 << " ";
  107.     }*/
  108.  
  109.     // Точки сочленения + нужно ll vita[N], good[N];
  110.     /*for (ll i = 0; i < n; ++i)
  111.         vita[i] = -1;
  112.  
  113.     for (ll i = 0; i < m; ++i) {
  114.         for (ll id : ans[i]) {
  115.             ll a = edges[id].first;
  116.             ll b = edges[id].second;
  117.             if (vita[a] != i && vita[a] != -1)
  118.                 good[a] = 1;
  119.             if (vita[b] != i && vita[b] != -1)
  120.                 good[b] = 1;
  121.  
  122.             vita[a] = vita[b] = i;
  123.         }
  124.     }
  125.     ll sz_ans = 0;
  126.     for (ll i = 0; i < n; ++i)
  127.         sz_ans += good[i];
  128.     cout << sz_ans << '\n';
  129.     for (ll i = 0; i < n; ++i)
  130.         if (good[i])
  131.             cout << i + 1 << " ";*/
  132. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement