Cod sursa(job #2967123)

Utilizator readyitzooDilirici Mihai readyitzoo Data 19 ianuarie 2023 02:11:26
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.98 kb
#include <iostream>
#include <fstream>
#include <list>
#include <vector>
#include <tuple>
#include <queue>

using namespace std;

ifstream f("cuplaj.in");
ofstream g("cuplaj.out");

int sizeLeft, sizeRight, edges;
int s, t;
vector < bool > inRight;
vector < pair < int, int >> parent, nodesRight;
vector < vector < pair < int, pair < int, int >>>> adjList;

void createEdge(int x, int y) {
    adjList[x].push_back({y, {1,adjList[y].size()}});
    adjList[y].push_back({x, {0,adjList[x].size() - 1}});

    if (y == t) {
        nodesRight.emplace_back(x, adjList[x].size() - 1);
    }
}

bool bf() {
    vector < bool > visited(t+1);
    queue < int > q;
    q.push(s);
    visited[s] = true;
    parent[s] = {-1, -1};

    while (!q.empty()) {
        int firstInQueue = q.front();
        q.pop();

        if (firstInQueue == t) {
            continue;
        }

        int i = 0;
        for (auto const& adjNode: adjList[firstInQueue]) {
            int c = adjNode.second.first;
            int node = adjNode.first;

            if (!visited[node] && c) {
                parent[node] = {firstInQueue, i};
                visited[node] = true;
                q.push(node);
            }

            ++i;
        }
    }

    return visited[t];
}

long long int cuplaj() {
    long long int maxFlow = 0;

    while (bf()) {
        for (auto const& adjNode: nodesRight) {
            int currentFlow = 1;
            parent[t] = adjNode;
            int y = t;

            while (parent[y].first != -1) {
                int u = parent[y].first;
                int v = parent[y].second;
                currentFlow = min(currentFlow, adjList[u][v].second.first);
                y = u;
            }

            y = t;
            while (parent[y].first != -1) {
                int u = parent[y].first;
                int v = parent[y].second;
                int w = adjList[u][v].second.second;

                adjList[u][v].second.first -= currentFlow;
                adjList[y][w].second.first += currentFlow;

                y = u;
            }

            maxFlow += currentFlow;
        }
    }

    return maxFlow;
}

int main() {
    f >> sizeLeft >> sizeRight >> edges;

    t = sizeLeft + sizeRight + 1;
    inRight.resize(sizeRight + 1);
    parent.resize(t + 1);
    adjList.resize(t + 1);

    for (int i = 1; i <= sizeLeft; ++i) {
        createEdge(s, i);
    }

    for (int i = 1; i <= edges; ++i) {
        int x, y;
        f>> x >> y;
        createEdge(x, sizeLeft + y);
        inRight[y] = true;
    }

    for (int i = 1; i <= sizeRight; ++i) {
        if (inRight[i]) {
            createEdge(sizeLeft + i, t);
        }
    }

    g << cuplaj() << '\n';
    for (int u = 1; u <= sizeLeft; ++u) {
        for (auto const &node: adjList[u]) {
            int vertex, capacity;

            vertex = node.first;
            capacity = node.second.first;

            if (vertex && capacity == 0 && vertex != t) {
                g << u << " " << vertex - sizeLeft << '\n';
            }
        }
    }
}