Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <algorithm>
- #include <vector>
- #include <unordered_set>
- typedef std::vector<int> iVec;
- typedef std::unordered_multiset<int> iumSet;
- typedef std::unordered_set<int> iuSet;
- typedef std::vector<bool> bVec;
- typedef std::vector<iumSet> matr;
- matr G, Gt;
- std::vector<iuSet> Comps;
- bVec used;
- iVec order;
- void topsort( int v )
- {
- used[v] = true;
- for (auto i : G[v])
- if (!used[i])
- topsort(i);
- order.push_back(v);
- }
- void dfs( int v, int cur_comp )
- {
- used[v] = true;
- Comps[cur_comp].insert(v);
- for (auto i : Gt[v])
- if (!used[i])
- dfs(i, cur_comp);
- }
- int main()
- {
- int n = 0, m = 0, i = 0, j = 0;
- // Obtain G and Gt (transposed)
- scanf("%i%i", &n, &m);
- G.resize(n);
- Gt.resize(n);
- used.resize(n);
- while (m--)
- {
- scanf("%i%i", &i, &j);
- G[--i].insert(--j);
- Gt[j].insert(i);
- }
- // Sort G
- std::generate(used.begin(), used.end(), []() { return false; });
- for (i = 0; i < n; ++i)
- if (!used[i])
- topsort(i);
- int cnt = 0;
- // Collect comps in Gt
- std::generate(used.begin(), used.end(), []() { return false; });
- for (i = 0; i < n; ++i)
- {
- int v = order[n - 1 - i];
- Comps.push_back(iuSet());
- if (!used[v])
- dfs(v, cnt++);
- }
- cnt = 0;
- // Count edges
- used.resize(Comps.size());
- std::generate(used.begin(), used.end(), []() { return false; });
- for (i = 0; i < Comps.size(); i++)
- for (j = 0; j < Comps.size(); j++)
- {
- if (i == j)
- continue;
- // check edges btw comps
- for (auto a : Comps[i])
- {
- if (used[i] && used[j]) // to skip duplicating edges
- break;
- for (auto b : Comps[j])
- {
- bool
- res1 = std::find(G[a].begin(), G[a].end(), b) != G[a].end(),
- res2 = std::find(G[b].begin(), G[b].end(), a) != G[b].end();
- if (res1 || res2)
- {
- used[i] = used[j] = true;
- if (res1 && res2)
- {
- // merge comps, vstrechnye rebra
- Comps[i].insert(Comps[j].begin(), Comps[j].end());
- Comps.erase(Comps.begin() + j);
- used.erase(used.begin() + j--);
- }
- else
- cnt++;
- break;
- }
- }
- }
- }
- std::cout << cnt;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement