Cod sursa(job #1395979)

Utilizator rootsroots1 roots Data 21 martie 2015 21:17:53
Problema Cuplaj maxim in graf bipartit Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.33 kb
#include <fstream>
#include <vector>
#include <cstring>

#define MAXV 10001

using namespace std;

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

int L, R, E;
vector <int> G[2 * MAXV];
int match[2 * MAXV];
int father[2 * MAXV];
int maxMatch = 0;
int root;
int firstUnmatched;

inline void readAndBuild() {
    in >> L >> R >> E;
    
    int x, y;
    for (int e = 0; e < E; ++ e) {
        in >> x >> y;
        
        G[x].push_back(y + L);
        G[y + L].push_back(x);
    }
}

inline bool dfs(int node, int parity) {
    for (vector <int>::iterator it = G[node].begin(); it != G[node].end(); ++ it) {
        if ((match[*it] != node) == parity) {
            if (father[*it] == -1) {
                father[*it] = node;
                
                if (match[*it] == 0 && *it != root) {
                    match[node] = *it;
                    match[*it] = node;
                    return true;
                }
                bool foundPath = dfs(*it, 1 - parity);
                
                if (foundPath) {
                    if (parity == 1) {
                        match[node] = *it;
                        match[*it] = node;
                    }
                    return true;
                }
            }
        }
    }
    
    return false;
}

inline bool dfsLoop() {
    memset(father, -1, sizeof(father));
    
    for (int node = firstUnmatched; node > 0; -- node) {
        if (match[node] == 0) {
            root = node;
            father[node] = node;
            bool foundPath = dfs(node, 1);
            
            if (foundPath) {
                firstUnmatched = node;
                while (firstUnmatched <= L && match[firstUnmatched] != 0) {
                    firstUnmatched ++;
                }
                
                return true;
            }
        }
    }
    
    return false;
}

inline void bipartiteMatchingWithEdmondsBlossom() {
    firstUnmatched = L;
    
    for (bool existsAugmentingPath = dfsLoop(); existsAugmentingPath; existsAugmentingPath = dfsLoop()) {
        maxMatch ++;
    }
}

inline void printResult() {
    out << maxMatch << '\n';
    for (int i = 1; i <= L; ++ i)
        if (match[i]) {
            out << i << ' ' << match[i] - L << '\n';
        }
}

int main() {
    readAndBuild();
    bipartiteMatchingWithEdmondsBlossom();
    printResult();
    
    return 0;
}