Cod sursa(job #869630)

Utilizator savimSerban Andrei Stan savim Data 1 februarie 2013 21:29:02
Problema Cuplaj maxim in graf bipartit Scor 80
Compilator cpp Status done
Runda Arhiva educationala Marime 2.33 kb
#include <cstdio>
#include <vector>

using namespace std;

const int MAX_N = 20010;

int N, M, E;

int use[MAX_N], cuplaj[MAX_N], vine[MAX_N];

vector <int> G[MAX_N];

vector <int> first, second;

void cupleaza(int start) {
    first.clear();
    second.clear();

    first.push_back(start); use[start] = start;
    
    while (first.size()) {
/*        printf("****\n");
        for (vector <int>::iterator it = first.begin(); it != first.end(); ++it)
            printf("%d ", *it);
        printf("\n");*/

        for (vector <int>::iterator it = first.begin(); it != first.end(); ++it) {
            if (cuplaj[*it] && use[cuplaj[*it]] != start) {
                use[cuplaj[*it]] = start;

                second.push_back(cuplaj[*it]);
                vine[cuplaj[*it]] = *it;

            }
            else {
                int nod = *it;
                for (vector <int>::iterator it_opposite = G[nod].begin(); it_opposite != G[nod].end(); ++it_opposite)
                    if (use[*it_opposite] != start) {
                        use[*it_opposite] = start;

                        second.push_back(*it_opposite);
                        vine[*it_opposite] = *it;

                        if (*it_opposite > N && cuplaj[*it_opposite] == 0) { //am gasit lant alternant 
                            int nod = *it_opposite;
                            while (nod != 0) {
                                cuplaj[vine[nod]] = nod;
                                cuplaj[nod] = vine[nod];

                                nod = vine[vine[nod]];
                            }
    
                            return;
                        }
                    }
            }
        }

        swap(second, first);
        second.clear();
    }
}

void write() {
    int ans = 0;

    for (int i = 1; i <= N; i++)
        ans += (cuplaj[i] != 0);

    printf("%d\n", ans);
    for (int i = 1; i <= N; i++)
        if (cuplaj[i])
            printf("%d %d\n", i, cuplaj[i] - N);
}

int main() {

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

    scanf("%d %d %d", &N, &M, &E);

    for (int i = 1; i <= E; i++) {
        int x, y;
        scanf("%d %d", &x, &y);

        G[x].push_back(y + N);
        G[y + N].push_back(x);
    }

    for (int i = 1; i <= N; i++)
        if (!cuplaj[i])
            cupleaza(i);

    write();

    return 0;
}