Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <fstream>
- #include <cstdio>
- #include <string>
- #include <vector>
- #include <queue>
- #define MAX_EDGE_CAPACITY 1000001
- using namespace std;
- int check_in_vector(vector<int> vec, int elem){
- for (int i = 0; i < vec.size(); i++){
- if (vec[i] == elem) return 1;
- }
- return 0;
- }
- int ford_find_max_flow(int n, vector< vector<int> >table_adjacency){
- long long int max_flow = 0;
- int fake_source = n;
- int fake_sink = n + 1;
- while(true){
- vector<int> parents(n+2);
- vector<int> visited(n+2);
- for (int i = 0; i < n + 2; i++){
- parents[i] = -1;
- visited[i] = 0;
- }
- queue<int> connects;
- connects.push(fake_source);
- //цикл ниже бежит и строит любой возможный путь от истока к стоку путем запоминания предыдущего узла для следующего
- while(!connects.empty()){
- int node = connects.front();
- connects.pop();
- for (int i = 0; i < n + 2; i++)
- if ((!visited[i]) && (table_adjacency[node][i] > 0)){
- parents[i] = node;
- connects.push(i);
- visited[i] = 1;
- }
- }
- if (parents[fake_sink] == -1)
- return max_flow;
- int one_flow = MAX_EDGE_CAPACITY;
- int go_back = fake_sink;
- //возвращаемся по найденному пути, вычисляя поток, который можно пустить по нему
- while (go_back != fake_source){
- int parent = parents[go_back];
- one_flow = min(table_adjacency[parent][go_back], one_flow);
- go_back = parent;
- }
- max_flow += one_flow;
- //бежим по ребрам пути и вычитаем из пропускной способности вычисленный поток, а в обратном направлении прибавляем, дабы можно было найти в случае чего через это ребро более "лучший" поток
- go_back = fake_sink;
- while (go_back != fake_source){
- int parent = parents[go_back];
- table_adjacency[parent][go_back] -= one_flow;
- table_adjacency[go_back][parent] += one_flow;
- go_back = parent;
- }
- }
- return -1;
- }
- int main(){
- freopen("input.txt", "r", stdin);
- freopen("output.txt", "w", stdout);
- //считывание исходных данных
- int n;
- cin >> n;
- vector<int> nodes_types(n);
- for (int i = 0; i < n; i++)
- cin >> nodes_types[i];
- vector< vector<int> > matrix(n + 2);
- for (int i = 0; i < n + 2; i++)
- matrix[i].resize(n + 2);
- for (int i = 0; i < n; i++)
- for (int j = 0; j < n; j++)
- cin >> matrix[i][j];
- //<-Считывание исходных данных
- //запоминаем где были истоки и стоки, чтобы добавить так называемые граничные истоки и стоки с максимальной пропускной способностью
- //фейковый сток нужен, чтобы узнать, что мы действительно нашли путь от истока к стоку. Все стоки соединены в таблице смежности с фейковым стоком
- //фейковый исток соединен в таблице смежности со всеми истоками и из него мы будем искать сток
- vector<int> sources;
- vector<int> drains;
- for (int i = 0; i < n; i++){
- if (nodes_types[i] == 1) sources.push_back(i);
- if (nodes_types[i] == 2) drains.push_back(i);
- }
- for (int i = 0; i < n + 2; i++)
- for (int j = 0; j < n + 2; j++){
- if ((i == n) and (check_in_vector(sources, j))) matrix[i][j] = MAX_EDGE_CAPACITY;
- else if ((check_in_vector(drains, i)) and (j == n + 1)) matrix[i][j] = MAX_EDGE_CAPACITY;
- }
- cout << ford_find_max_flow(n, matrix);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement