Cod sursa(job #2962234)

Utilizator DevCrutCorolevschi Mihai DevCrut Data 8 ianuarie 2023 01:36:41
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.87 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<pair<int, pair<int, int>>>> adjList;
vector<vector<int>> capacityMap;
vector<pair<int,int>> parentMap;

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,-1 });

    for (int i = 1; i <= u; i++) {
        int indexA = adjList[i].size();
        int indexB = adjList[0].size();

        adjList[0].push_back({ i,{ 1,indexA } });
        adjList[i].push_back({ 0,{ 0,indexB } });
    }
    for (int i = u + 1; i < nodeCount - 1; i++) {
        int indexA = adjList[nodeCount - 1].size();
        int indexB = adjList[i].size();

        adjList[i].push_back({ nodeCount - 1,{ 1,indexA } });
        adjList[nodeCount - 1].push_back({ i,{ 0,indexB } });
    }

    int x, y;
    for (int i = 0; i < m; i++) {
        myIn >> x >> y; y = y + u;
        int indexA = adjList[y].size();
        int indexB = adjList[x].size();

        adjList[x].push_back({ y,{ 1,indexA } });
        adjList[y].push_back({ x,{ 0,indexB } });
    }
}

bool BFS() {
    //cout << "Citit";
    for (int i = 0; i < parentMap.size(); i++) {
        parentMap[i].first = -1; parentMap[i].second = -1;
    }
    queue<int> q;
    q.push(0);

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

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

        for (int i = 0; i < adjList[currentNode].size(); i++) {
            auto nodeData = adjList[currentNode][i];
            int nextNode = nodeData.first;
            int capacity = nodeData.second.first;
            if ((parentMap[nextNode].first == -1) && (capacity > 0)) {
                q.push(nextNode);
                parentMap[nextNode] = { currentNode,i };
            }
        }
    }
    return false;
}

void EdmondsKarp() {
    int x = 0;
    while (BFS()) {
        for (int linkIndex = 0; linkIndex < adjList[nodeCount - 1].size(); linkIndex++) {
            auto linkData = adjList[nodeCount - 1][linkIndex];
            int sinkNode = linkData.first;

            if (parentMap[sinkNode].first != -1) {
                parentMap[nodeCount - 1].first = sinkNode;
                parentMap[nodeCount - 1].second = linkData.second.second;
                int minFlow = INT_MAX;
                for (int node = (nodeCount - 1); node != 0; node = parentMap[node].first) {
                    int adjNode = parentMap[node].first;
                    auto prevNodeLink = adjList[adjNode][parentMap[node].second];
                    minFlow = min(minFlow, prevNodeLink.second.first);
                }
                if (minFlow <= 0) continue;

                for (int node = (nodeCount - 1); node != 0; node = parentMap[node].first) {
                    int adjNode = parentMap[node].first;

                    (adjList[node][(adjList[adjNode][parentMap[node].second]).second.second]).second.first += minFlow;
                    (adjList[adjNode][parentMap[node].second]).second.first -= minFlow;
                }

                maxFlow += minFlow;
            }
        }
    }
}

void Output() {
    myOut << maxFlow << '\n';
    for (int aNode = 1; aNode <= u; aNode++) {
        for (int j = 0; j < adjList[aNode].size(); j++) {
            int bNode = adjList[aNode][j].first;
            int capacity = adjList[aNode][j].second.first;
            if ((bNode > u) && (capacity == 0)) {
                myOut << aNode << ' ' << bNode - u << '\n';
            }
        }
    }
}

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