RedHotChiliPepper

Конденсация (ор)графа(петли, кратные)

Apr 21st, 2021 (edited)
229
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.11 KB | None | 0 0
  1. // Построим лес деревьев обхода, и отсортируем по убыванию времени выхода все вершины исходного графа
  2. // Заметим, что ребра между вершинами двух разных компонент с.с. идут слева направо(относ индексов в отсорченном)
  3. // Развернем все ребра и запустимся от самой "левой" вершины
  4. // мы не попадем в другие компоненты, так как ребра между ними перевернулись
  5. // мы найдем всю компоненту вершины, от которой запустились - v
  6. // так как от всех этих вершин можно дойти до v по определению(в перевернутом получается можно от v до них)
  7. // "удаляем" всю компоненту v и применяем те же рассуждения
  8.  
  9. const ll N = 2e5 + 100;
  10. vector<ll> g[N][3], comp[N];
  11. ll used[N], id[N];
  12.  
  13. void dfs(vector<ll>& orda, ll v, ll g_id = 0) {
  14.     used[v] = 1;
  15.     for (ll to : g[v][g_id])
  16.         if (!used[to])
  17.             dfs(orda, to, g_id);
  18.     orda.push_back(v);
  19. }
  20.  
  21. void $main()
  22. {
  23.     ll n, m; cin >> n >> m;
  24.     for (ll i = 0; i < m; ++i) {
  25.         ll v, u; cin >> v >> u;
  26.         --v; --u;
  27.         g[v][0].emplace_back(u);
  28.         g[u][1].emplace_back(v);
  29.     }
  30.  
  31.     vector<ll> orda;
  32.     for (ll i = 0; i < n; ++i)
  33.         if (!used[i])
  34.             dfs(orda, i);
  35.     fill(used, used + N, 0);
  36.  
  37.     ll top = 0;
  38.     for (ll j = n-1; j >= 0; --j) {
  39.         ll i = orda[j];
  40.         if (!used[i]) {
  41.             dfs(comp[top], i, 1);
  42.             for (ll el : comp[top])
  43.                 id[el] = top;
  44.             ++top;
  45.         }
  46.     }
  47.     fill(used, used + N, 0);
  48.  
  49.     for (ll i = 0; i < n; ++i)
  50.         for (ll to : g[i][2])
  51.             g[id[i]][2].push_back(id[to]);
  52.  
  53.     vector<ll> meta_orda;
  54.     for (ll i = 0; i < top; ++i)
  55.         if (!used[i])
  56.             dfs(meta_orda, i, 2);
  57.  
  58.     vector<ll> ans(n);
  59.     ll it = 1;
  60.     for (ll cid : meta_orda) {
  61.         for (ll el : comp[cid])
  62.             ans[el] = it;
  63.         ++it;
  64.     }
  65.     cout << top << '\n';
  66.     for (ll el : ans)
  67.         cout << el << " ";
  68. }
Add Comment
Please, Sign In to add comment