fork(1) download
  1. // Code written by JadeMasochist
  2.  
  3. #include <bits/stdc++.h>
  4. using namespace std;
  5.  
  6. #define LL long long
  7. typedef vector<LL> vi;
  8.  
  9.  
  10. LL n, m, SCCcnt = 0; // Basic variables.
  11. LL Time = 0; // Used to track the traversing order.
  12. vector<vi> adj; vi Lowest, Enum; // Store essential informations.
  13. // adj: Adjacency lists.
  14. // Enum: The traversing position of a node.
  15. // Lowest: The lowest position of any nodes within the same SCC as the current one.
  16. stack<LL> S; // Keep the currently working nodes (incomplete SCC).
  17.  
  18. void traverse(LL z) {
  19. Lowest[z] = ++Time; Enum[z] = Time; S.push(z);
  20. for (LL i=0; i<adj[z].size(); i++) {
  21. if (Enum[adj[z][i]] != 0) Lowest[z] = min(Lowest[z], Lowest[adj[z][i]]); // Traversed node - update Lowest value.
  22. else {
  23. traverse(adj[z][i]); // Untraversed node, so traverse it.
  24. Lowest[z] = min(Lowest[z], Lowest[adj[z][i]]); // Update the new Lowest value.
  25. }
  26. }
  27.  
  28. if (Enum[z] == Lowest[z]) { // Lowest node found - SCC completed
  29. SCCcnt++; LL t;
  30. do {
  31. t = S.top(); S.pop();
  32. Lowest[t] = 1e18; Enum[t] = 1e18; // Remove every vertex on the SCC out of traversion.
  33. }
  34. while (z != t);
  35. }
  36. }
  37.  
  38. int main() {
  39. ios_base::sync_with_stdio(0);
  40. cin.tie(0); cout.tie(0);
  41. cin >> n >> m; adj.resize(n+1, vi(0));
  42. while (m--) {
  43. LL u, v; cin >> u >> v;
  44. adj[u].push_back(v);
  45. }
  46. Lowest.resize(n+1, 0); Enum = Lowest;
  47. for (LL i=1; i<=n; i++) {
  48. if (Lowest[i] == 0) traverse(i);
  49. }
  50. cout << SCCcnt;
  51. return 0;
  52. }
Success #stdin #stdout 0s 4404KB
stdin
8 14
1 2
2 3
3 1
4 2
4 3
4 5
5 4
5 6
6 3
6 7
7 6
8 5
8 6
8 8
stdout
4