Cod sursa(job #1252874)

Utilizator gabrieligabrieli gabrieli Data 31 octombrie 2014 14:53:51
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.91 kb
#include <algorithm>
#include <fstream>
#include <vector>
using namespace std;

bool findMatch(
        const int u,
        vector<int>& matchInU,
        vector<int>& matchInV,
        vector<bool>& tested,
        const vector<vector<int>>& E) {
    if (tested[u]) return false;
    tested[u] = true;
    
    for (int v : E[u])
        if (matchInU[v] == -1 ||
                findMatch(matchInU[v], matchInU, matchInV, tested, E)) {
            // if v is unmatched or if we can free v
        matchInU[v] = u;
        matchInV[u] = v;
        return true;
    }
    
    return false;
}

int main() {
    ifstream fin("cuplaj.in");
    ofstream fout("cuplaj.out");
    
    int nU, nV, edges; fin >> nU >> nV >> edges;
    // Representation of a bipartite graph G = (U + V, E), stores only the edges
    // linking nodes in U to nodes in V i.e. for any u in U, if v in E[u] then
    // there is an edge (u, v) in E.
    // U = {0, 1, ..., nU-1}, V = {0, 1, ..., nV-1}
    vector<vector<int>> E(nU);
    
    for (int u, v; edges--;) {
        fin >> u >> v; u--, v--;
        
        E[u].push_back(v);
    }

    // keep track of the vertices in U which we have already tried to match
    vector<bool> tested(nU, false);    
    
    vector<int> matchInU(nV, -1), // map from V to U
                matchInV(nU, -1); // map from U to V
 
    // greedy algorithm to find the maximum matching
    int max_matching = 0;
    for (bool changed = true; changed; ) {
        changed = false;
        
        fill(tested.begin(), tested.end(), false);
        for (int u = 0; u < nU; ++u)
            if (matchInV[u] == -1 && findMatch(u, matchInU, matchInV, tested, E)) {
                changed = true;
                max_matching++;
            }
    }
    
    // output a maximum matching
    fout << max_matching << '\n';
    for (int u = 0; u < nU; ++u) if (matchInV[u] != -1)
        fout << u+1 << ' ' << matchInV[u]+1 << '\n';
    
    return 0;
}