Cod sursa(job #2961592)

Utilizator DevCrutCorolevschi Mihai DevCrut Data 6 ianuarie 2023 19:00:06
Problema Cuplaj maxim in graf bipartit Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.23 kb
#include <fstream>
#include <vector>
#include <iostream>
#include <string.h>
#include <string>
#include <sstream>
#include <climits>
#include <queue>

using namespace std;

int u, v, m, maxFlow;
int nodeCount;
vector<vector<int>> adjList;
vector<vector<int>> capacityMap;
vector<int> parentMap;
vector < pair<int , int> > result;

ifstream myIn("cuplaj.in");
ofstream myOut("cuplaj.out");

void ReadInputs() {
    myIn >> u >> v >> m;
    nodeCount = u + v + 2;


    adjList.resize(nodeCount, {});
    parentMap.resize(nodeCount, -1);
    capacityMap.resize(nodeCount, vector<int>(nodeCount, 0));


    for (int i = 1; i <= u; i++) {
        adjList[0].push_back(i);
        adjList[i].push_back(0);
        capacityMap[0][i] = 1;
    }
    for (int i = u + 1; i <= u + v; i++) {
        adjList[i].push_back(nodeCount - 1);
        adjList[nodeCount - 1].push_back(i);
        capacityMap[i][nodeCount - 1] = 1;
    }

    int x, y;
    for (int i = 0; i < m; i++) {
        myIn >> x >> y; y = y + u;
        adjList[x].push_back(y);
        adjList[y].push_back(x);
        capacityMap[x][y] = 1;
    }
}

bool BFS() {
    fill(parentMap.begin(), parentMap.end(), -1);
    queue<int> q;
    q.push(0);

    while (not q.empty()) {
        int currentNode = q.front();
        q.pop();

        if (currentNode == nodeCount-1) {
            return true;
        }

        for (const auto& nextNode : adjList[currentNode]) {
            int capacity = capacityMap[currentNode][nextNode];
            if ((parentMap[nextNode] == -1) && (capacity > 0)) {
                q.push(nextNode);
                parentMap[nextNode] = currentNode;
            }
        }
    }
    return false;
}

void EdmondsKarp() {
    while (BFS()) {
        for (const auto& prevNode : adjList[nodeCount - 1]) {
            if (parentMap[prevNode] != -1) {
                parentMap[nodeCount - 1] = prevNode;
                int minFlow = INT_MAX;

                int nodeA = -1;
                int nodeB = -1;
                for (int node = (nodeCount - 1); node != 0; node = parentMap[node]) {
                    int prevNode = parentMap[node];
                    if (node != (nodeCount - 1))
                        if (nodeB == -1) {
                            nodeB = node - u;
                        }
                        else if (nodeA == -1) {
                            nodeA = node;
                        }
                    minFlow = min(minFlow, capacityMap[prevNode][node]);
                }
                if (minFlow <= 0) continue;

                result.push_back({ nodeA, nodeB });

                for (int node = (nodeCount - 1); node != 0; node = parentMap[node]) {
                    int prevNode = parentMap[node];
                    capacityMap[node][prevNode] += minFlow;
                    capacityMap[prevNode][node] -= minFlow;
                }

                maxFlow += minFlow;
            }
        }
    }
}

void Output() {
    myOut << maxFlow << '\n';
    for (int i = 0; i < result.size(); i++) {
        myOut << result[i].first << ' ' << result[i].second << '\n';
    }
}

int main() {
    ReadInputs();
    EdmondsKarp();
    Output();
}