Cod sursa(job #2011374)

Utilizator EuAlexOtaku Hikikomori EuAlex Data 15 august 2017 22:27:43
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.08 kb
#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>

using namespace std;

const int nmax = 10000;

int u, v, m;
vector <int> g[1 + 2 * nmax];
queue <int> q;
int match[1 + 2 * nmax], dist[1 + nmax];
bool viz[1 + nmax];

void bfs() {
    for(int i = 1; i <= u; ++ i) {
        if(match[i] == 0) {
            q.push(i);
            dist[i] = 0;
        } else {
            dist[i] = -1;
        }
    }

    while(!q.empty()) {
        int u1 = q.front();
        for(int k = 0; k < g[u1].size(); ++ k) {
            int v1 = g[u1][k], u2 = match[v1];
            if(dist[u2] == -1 && u2 != 0) {
                q.push(u2);
                dist[u2] = dist[u1] + 1;
            }
        }
        q.pop();
    }
}

int dfs(int u1) {
    viz[u1] = 1;

    for(int k = 0; k < g[u1].size(); ++ k) {
        int v1 = g[u1][k], u2 = match[v1];
        if(u2 == 0) {
            match[u1] = v1;
            match[v1] = u1;
            return 1;
        } else if(viz[u2] == 0 && dist[u2] == dist[u1] + 1) {
            if(dfs(u2)) {
                match[u1] = v1;
                match[v1] = u1;
                return 1;
            }
        }
    }

    return 0;
}

int maxMatch() {
    int raspuns = 0, adaug = 1;

    while(adaug > 0) {
        adaug = 0;
        bfs();
        fill(viz + 1, viz + u + 1, 0);
        for(int i = 1; i <= u; ++ i) {
            if(match[i] == 0) {
                if(dfs(i)) {
                    ++ adaug;
                }
            }
        }
        raspuns += adaug;
    }

    return raspuns;
}

int main() {
    freopen("cuplaj.in", "r", stdin);
    freopen("cuplaj.out", "w", stdout);

    scanf("%d%d%d", &u ,&v, &m);

    for(int i = 1; i <= m; ++ i) {
        int x, y;
        scanf("%d%d", &x, &y);
        y += u;
        g[x].push_back(y);
        g[y].push_back(x);
    }

    printf("%d\n", maxMatch());

    for(int i = 1; i <= u; ++ i) {
        if(match[i] != 0) {
            printf("%d %d\n", i, match[i] - u);
        }
    }

    return 0;
}