Cod sursa(job #2986959)

Utilizator MihaiZ777MihaiZ MihaiZ777 Data 1 martie 2023 18:38:29
Problema Cuplaj maxim in graf bipartit Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.86 kb
#include <iostream>
#include <fstream>
#include <queue>
#include <cstring>
#include <vector>
using namespace std;

ifstream fin("cuplaj.in");
ofstream fout("cuplaj.out");

const int INF = 0x3f3f3f3f;
const int MAX_N = 15005;
int SOURCE = 0;
int DESTINATION = MAX_N;

struct Edge {
    int a, b;
};

int n, m;   // cardinal
int e;      // edges
int graph[MAX_N][MAX_N];
int flow[MAX_N][MAX_N];
int father[MAX_N];
vector <int> BFSGraph[MAX_N];
queue <int> q;
vector <Edge> edges;
vector <Edge> cuplaj;


void AddSource() {
    for (int i = 1; i <= n; i++) {
        graph[SOURCE][i] = 1;

        BFSGraph[SOURCE].push_back(i);
        BFSGraph[i].push_back(SOURCE);
    }
}

void AddDestination() {
    for (int i = n + 1; i <= n + m; i++) {
        graph[i][DESTINATION] = 1;

        BFSGraph[DESTINATION].push_back(i);
        BFSGraph[i].push_back(DESTINATION);
    }
}

void InitQueue() {
    while (!q.empty()) {
        q.pop();
    }
    q.push(SOURCE);
}

bool BFS() {
    InitQueue();

    memset(father, -1, sizeof(father));
    father[SOURCE] = SOURCE;

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

        if (node == DESTINATION) {
            return true;
        }

        for (int newNode : BFSGraph[node]) {
            if (father[newNode] == -1 && graph[node][newNode] - flow[node][newNode] > 0) {
                father[newNode] = node;
                q.push(newNode);
            }
        }
    }
    return false;
}

int GetMinimumCapacity() {
    int node = DESTINATION;
    int minimumCapacity = INF;

    while (father[node] != node) {
        int parent = father[node];
        minimumCapacity = min(minimumCapacity, graph[parent][node] - flow[parent][node]);
        node = parent;
    }
    return minimumCapacity;
}

void UpdateFlow(int value) {
    int node = DESTINATION;
    
    while (father[node] != node) {
        int parent = father[node];
        flow[parent][node] += value;
        flow[node][parent] -= value;
        node = parent;
    }
}

void BuildCuplaj() {
    for (Edge edge : edges) {
        if (flow[edge.a][edge.b] == 1) {
            cuplaj.push_back(edge);
        }   
    }

    fout << cuplaj.size() << '\n';
    for (Edge edge : cuplaj) {
        fout << edge.a << ' ' << edge.b - n << '\n';
    }
}

int main() {
    fin >> n >> m >> e;
    DESTINATION = n + m + 1;

    for (int i = 1; i <= e; i++) {
        int a, b;
        fin >> a >> b;

        b += n;
        graph[a][b] = 1;
        
        BFSGraph[a].push_back(b);
        BFSGraph[b].push_back(a);

        edges.push_back({a, b});
    }

    AddSource();
    AddDestination();

    while (BFS()) {
        int minimumCapacity = GetMinimumCapacity();
        UpdateFlow(minimumCapacity);
    }   

    BuildCuplaj();

    return 0;
}