Advertisement
a53

drumuri2

a53
Jan 31st, 2021
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.44 KB | None | 0 0
  1. #include <iostream>
  2. #include <fstream>
  3. #include <vector>
  4. #include <stack>
  5. #include <algorithm>
  6.  
  7. using namespace std;
  8.  
  9. ostream& operator<<(ostream& cout, const vector<int> &V) {
  10. cout << V.size() << "\n";
  11.  
  12. for (vector<int>::const_iterator it = V.begin(); it != V.end(); ++it)
  13. cout << *it + 1 << " ";
  14. cout << "\n";
  15. return cout;
  16. }
  17.  
  18.  
  19. class Graph {
  20. public:
  21. Graph(const int &size):
  22. edges_(size) {
  23. }
  24.  
  25. void addArc(const int &from, const int &to) {
  26. edges_[from].push_back(to);
  27. }
  28.  
  29. vector<int> kernels() {
  30. lowlink = index = scc = vector<int>(edges_.size(), 0);
  31. indecs = 0;
  32.  
  33. for (int i = 0; i < int(edges_.size()); ++i) {
  34. tarjan(i);
  35. }
  36.  
  37. vector<int> bestLeft(sccs.size(), 1), bestRight(sccs.size(), 1), aux(sccs.size(), 1);
  38. for (int i = 0; i < int(sccs.size()); ++i) {
  39. for (vector<int>::iterator it = sccs[i].begin(); it != sccs[i].end(); ++it)
  40. for (vector<int>::iterator jt = edges_[*it].begin(); jt != edges_[*it].end(); ++jt)
  41. if (i != scc[*jt]) {
  42. aux[i] += aux[scc[*jt]];
  43. aux[scc[*jt]] = 0;
  44. }
  45. bestLeft[i] = aux[i];
  46. }
  47.  
  48. vector<bool> ok(edges_.size(), false);
  49. int total = 0;
  50. for (int i = sccs.size() - 1; i >= 0; --i) {
  51. if (bestLeft[i] + bestRight[i] == int(sccs.size()) + 1) {
  52. total += sccs[i].size();
  53. for (vector<int>::iterator it = sccs[i].begin(); it != sccs[i].end(); ++it)
  54. ok[*it] = true;
  55. }
  56.  
  57. int minplace = -1;
  58. for (vector<int>::iterator it = sccs[i].begin(); it != sccs[i].end(); ++it)
  59. for (vector<int>::iterator jt = edges_[*it].begin(); jt != edges_[*it].end(); ++jt)
  60. if (i > scc[*jt] && scc[*jt] > minplace)
  61. minplace = scc[*jt];
  62.  
  63. if (minplace != -1)
  64. bestRight[minplace] += bestRight[i];
  65. }
  66.  
  67. vector<int> answer;
  68. answer.reserve(total);
  69. for (int i = 0; i < int(edges_.size()); ++i)
  70. if (ok[i])
  71. answer.push_back(i);
  72. return answer;
  73. }
  74.  
  75. private:
  76. void tarjan(const int &node) {
  77. if (lowlink[node] != 0)
  78. return;
  79.  
  80. index[node] = lowlink[node] = ++indecs;
  81. S.push(node);
  82.  
  83. for (vector<int>::iterator it = edges_[node].begin(); it != edges_[node].end(); ++it)
  84. if (index[*it] == 0) {
  85. tarjan(*it);
  86. lowlink[node] = min(lowlink[node], lowlink[*it]);
  87. } else
  88. if (index[*it] != -1) {
  89. lowlink[node] = min(lowlink[node], lowlink[*it]);
  90. }
  91.  
  92. //cerr << node + 1 << " -> " << lowlink[node] << " " << index[node] << "\n";
  93. if (lowlink[node] == index[node]) {
  94. vector<int> now;
  95. int nod;
  96. do {
  97. nod = S.top();
  98. S.pop();
  99. now.push_back(nod);
  100. scc[nod] = sccs.size();
  101. index[nod] = -1;
  102. } while (nod != node);
  103.  
  104. sccs.push_back(now);
  105. }
  106.  
  107. }
  108.  
  109. void randomSort() {
  110. for (int i = 0; i < int(sccs.size()); ++i)
  111. random_shuffle(E[i].begin(), E[i].end());
  112.  
  113. vector<int> list(sccs.size());
  114. for (int i = 0; i < int(sccs.size()); ++i)
  115. list[i] = i;
  116. random_shuffle(list.begin(), list.end());
  117.  
  118. top.clear();
  119. been = vector<bool>(sccs.size(), false);
  120. for (int i = 0; i < int(sccs.size()); ++i)
  121. dfs(list[i]);
  122. }
  123.  
  124. void dfs(int nod) {
  125. if (been[nod])
  126. return;
  127. been[nod] = true;
  128. for (vector<int>::iterator it = E[nod].begin(); it != E[nod].end(); ++it)
  129. dfs(*it);
  130.  
  131. top.push_back(nod);
  132. }
  133.  
  134. stack<int> S;
  135. vector< vector<int> > sccs;
  136. vector<int> index, lowlink, scc;
  137. int indecs;
  138. vector< vector<int> > edges_, E;
  139. vector<int> top;
  140. vector<bool> been;
  141. };
  142.  
  143. int main() {
  144. ifstream cin("drumuri.in");
  145. ofstream cout("drumuri.out");
  146.  
  147. int N, M; cin >> N >> M;
  148. Graph G(N);
  149. for (int i = 0; i < M; ++i) {
  150. int x, y; cin >> x >> y;
  151. G.addArc(x - 1, y - 1);
  152. }
  153.  
  154. cout << G.kernels();
  155. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement