Advertisement
wurdalak007

Untitled

Feb 22nd, 2018
424
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.23 KB | None | 0 0
  1. /*Дан ориентированный граф. Определите, какое минимальное число ребер необходимо добавить, чтобы граф стал сильносвязным.*/
  2.  
  3. #include <iostream>
  4. #include <vector>
  5.  
  6. using namespace std;
  7.  
  8. class Graph {
  9. public:
  10. Graph( int n );
  11. void AddEdge( int from, int to );
  12. int num_of_edges();
  13.  
  14. private:
  15. vector<vector<int>> graph;
  16. vector<vector<int>> t_graph;
  17. vector<bool> used;
  18. vector<int> order, component;
  19. vector<int> which_comp;
  20. vector< vector<int> > all_components;
  21.  
  22. void first_dfs(int v);
  23. void sec_dfs(int v);
  24. void find_comp();
  25. void fill_which_comp();
  26. };
  27.  
  28. Graph::Graph( int n ): graph(n), t_graph(n), used(n, false), which_comp(n) {}
  29.  
  30. int Graph::num_of_edges() {
  31. int stock = 0;
  32. int not_stock = 0;
  33. find_comp();
  34. fill_which_comp();
  35.  
  36. if( all_components.size() == 1 ) return 0;
  37.  
  38. for( int comp = 0; comp < all_components.size(); comp++ ) {
  39. bool find_edge = true;
  40. for( int vert : all_components[comp] ) {
  41. for( int child : graph[vert] ) {
  42. if( which_comp[child] != comp ) {
  43. find_edge = false;
  44. }
  45. }
  46. }
  47. if( find_edge ) {
  48. stock++;
  49. }
  50. }
  51.  
  52. for( int comp = 0; comp < all_components.size(); comp++ ) {
  53. bool find_edge = true;
  54. for( int vert : all_components[comp] ) {
  55. for( int child : t_graph[vert] ) {
  56. if( which_comp[child] != comp ) {
  57. find_edge = false;
  58. }
  59. }
  60. }
  61. if( find_edge ) {
  62. not_stock++;
  63. }
  64. }
  65.  
  66. return max(stock, not_stock);
  67. }
  68.  
  69. void Graph::fill_which_comp() {
  70. for( int i = 0; i < all_components.size(); i++ ){
  71. for( int j : all_components[i] ) {
  72. which_comp[j] = i;
  73. }
  74. }
  75. }
  76.  
  77. void Graph::AddEdge( int from, int to ) {
  78. graph[from].push_back(to);
  79. t_graph[to].push_back(from);
  80. }
  81.  
  82. void Graph::first_dfs( int v ) {
  83. used[v] = true;
  84. for( int i = 0; i < graph[v].size(); i++ )
  85. if( !used[ graph[v][i] ] )
  86. first_dfs( graph[v][i] );
  87. order.push_back(v);
  88. }
  89.  
  90. void Graph::sec_dfs( int v ) {
  91. used[v] = true;
  92. component.push_back (v);
  93. for( int i = 0; i < t_graph[v].size(); i++ )
  94. if( !used[ t_graph[v][i] ] )
  95. sec_dfs( t_graph[v][i] );
  96. }
  97.  
  98. void Graph::find_comp() {
  99. int n = (int)graph.size();
  100. used.assign (n, false);
  101.  
  102. for( int i = 0; i < n; i++ )
  103. if( !used[i] )
  104. first_dfs(i);
  105.  
  106. used.assign (n, false);
  107. for( int i = 0; i < n; i++ ) {
  108. int v = order[n-1-i];
  109. if( !used[v] ) {
  110. sec_dfs(v);
  111. all_components.push_back(component);
  112. component.clear();
  113. }
  114. }
  115. }
  116.  
  117. int main() {
  118. int vertex = 0;
  119. int edges = 0;
  120. cin >> vertex >> edges;
  121.  
  122. Graph graph(vertex);
  123. for( int i = 0; i < edges; i++ ) {
  124. int from,to;
  125. cin >> from >> to;
  126. graph.AddEdge(from-1, to-1);
  127. }
  128.  
  129. cout << graph.num_of_edges();
  130.  
  131. return 0;
  132. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement