Cod sursa(job #1676168)

Utilizator bciobanuBogdan Ciobanu bciobanu Data 5 aprilie 2016 19:12:04
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.75 kb
#include <bits/stdc++.h>
using namespace std;

const int MAX_N = 10000;
const int MAX_M = 100000;
const int NIL = -1;

struct Edge {
    int v;
    int next;
};
Edge G[MAX_M];
int head[2 * MAX_N];

bool used[MAX_N];
int L[MAX_N], R[MAX_N];

bool pairUp(int u) {
    if (used[u]) {
        return false;
    }
    used[u] = true;

    int i = head[u];
    while (i != NIL && R[G[i].v] != NIL) {
        i = G[i].next;
    }
    if (i == NIL) {
        i = head[u];
        while (i != NIL && !pairUp(R[G[i].v])) {
            i = G[i].next;
        }
    }
    if (i != NIL) {
        L[u] = G[i].v;
        R[G[i].v] = u;
        return true;
    } else {
        return false;
    }
}

void matching(int n, int m) {
    bool pushed;

    memset(L, NIL, 4 * n);
    memset(R, NIL, 4 * m);

    do {
        pushed = false;
        memset(used, 0, n);
        for (int i = 0; i < n; ++ i) {
            if (L[i] == NIL) {
                pushed |= pairUp(i);
            }
        }
    } while (pushed);
}

int main() {
    ifstream fin("cuplaj.in");
    ofstream fout("cuplaj.out");
    fin.tie(0);
    ios_base::sync_with_stdio(false);

    int n, m, k; fin >> n >> m >> k;

    memset(head, NIL, 4 * (n + m));

    for (int i = 0; i < k; ++ i) {
        int u, v; fin >> u >> v;
        G[i].v = v - 1;
        G[i].next = head[u - 1];
        head[u - 1] = i;
    }

    matching(n, m);

    int flow = 0;
    for (int i = 0; i < n; ++ i) {
        flow += (L[i] != NIL);
    }

    fout << flow << '\n';

    for (int i = 0; i < n; ++ i) {
        if (L[i] != NIL) {
            fout << 1 + i << ' ' << 1 + L[i] << '\n';
        }
    }
    fout.close();
    fout.close();

    return 0;
}