Advertisement
Guest User

Untitled

a guest
Oct 21st, 2017
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.80 KB | None | 0 0
  1. #include <iostream>
  2. #include <fstream>
  3. #include <cstdio>
  4. #include <string>
  5. #include <vector>
  6. #include <queue>
  7.  
  8. #define MAX_EDGE_CAPACITY 1000001
  9.  
  10. using namespace std;
  11.  
  12. int check_in_vector(vector<int> vec, int elem){
  13. for (int i = 0; i < vec.size(); i++){
  14. if (vec[i] == elem) return 1;
  15. }
  16. return 0;
  17. }
  18.  
  19. int ford_find_max_flow(int n, vector< vector<int> >table_adjacency){
  20. long long int max_flow = 0;
  21. int fake_source = n;
  22. int fake_sink = n + 1;
  23. while(true){
  24. vector<int> parents(n+2);
  25. vector<int> visited(n+2);
  26. for (int i = 0; i < n + 2; i++){
  27. parents[i] = -1;
  28. visited[i] = 0;
  29. }
  30. queue<int> connects;
  31. connects.push(fake_source);
  32.  
  33. //цикл ниже бежит и строит любой возможный путь от истока к стоку путем запоминания предыдущего узла для следующего
  34. while(!connects.empty()){
  35. int node = connects.front();
  36. connects.pop();
  37. for (int i = 0; i < n + 2; i++)
  38. if ((!visited[i]) && (table_adjacency[node][i] > 0)){
  39. parents[i] = node;
  40. connects.push(i);
  41. visited[i] = 1;
  42. }
  43. }
  44.  
  45. if (parents[fake_sink] == -1)
  46. return max_flow;
  47.  
  48. int one_flow = MAX_EDGE_CAPACITY;
  49. int go_back = fake_sink;
  50.  
  51. //возвращаемся по найденному пути, вычисляя поток, который можно пустить по нему
  52.  
  53. while (go_back != fake_source){
  54. int parent = parents[go_back];
  55. one_flow = min(table_adjacency[parent][go_back], one_flow);
  56. go_back = parent;
  57. }
  58.  
  59. max_flow += one_flow;
  60.  
  61. //бежим по ребрам пути и вычитаем из пропускной способности вычисленный поток, а в обратном направлении прибавляем, дабы можно было найти в случае чего через это ребро более "лучший" поток
  62.  
  63. go_back = fake_sink;
  64.  
  65. while (go_back != fake_source){
  66. int parent = parents[go_back];
  67. table_adjacency[parent][go_back] -= one_flow;
  68. table_adjacency[go_back][parent] += one_flow;
  69. go_back = parent;
  70. }
  71.  
  72. }
  73. return -1;
  74. }
  75.  
  76. int main(){
  77. freopen("input.txt", "r", stdin);
  78. freopen("output.txt", "w", stdout);
  79. //считывание исходных данных
  80. int n;
  81. cin >> n;
  82. vector<int> nodes_types(n);
  83. for (int i = 0; i < n; i++)
  84. cin >> nodes_types[i];
  85. vector< vector<int> > matrix(n + 2);
  86. for (int i = 0; i < n + 2; i++)
  87. matrix[i].resize(n + 2);
  88. for (int i = 0; i < n; i++)
  89. for (int j = 0; j < n; j++)
  90. cin >> matrix[i][j];
  91. //<-Считывание исходных данных
  92.  
  93. //запоминаем где были истоки и стоки, чтобы добавить так называемые граничные истоки и стоки с максимальной пропускной способностью
  94. //фейковый сток нужен, чтобы узнать, что мы действительно нашли путь от истока к стоку. Все стоки соединены в таблице смежности с фейковым стоком
  95. //фейковый исток соединен в таблице смежности со всеми истоками и из него мы будем искать сток
  96.  
  97. vector<int> sources;
  98. vector<int> drains;
  99. for (int i = 0; i < n; i++){
  100. if (nodes_types[i] == 1) sources.push_back(i);
  101. if (nodes_types[i] == 2) drains.push_back(i);
  102. }
  103.  
  104. for (int i = 0; i < n + 2; i++)
  105. for (int j = 0; j < n + 2; j++){
  106. if ((i == n) and (check_in_vector(sources, j))) matrix[i][j] = MAX_EDGE_CAPACITY;
  107. else if ((check_in_vector(drains, i)) and (j == n + 1)) matrix[i][j] = MAX_EDGE_CAPACITY;
  108. }
  109.  
  110. cout << ford_find_max_flow(n, matrix);
  111. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement