Cod sursa(job #1014678)

Utilizator sziliMandici Szilard szili Data 23 octombrie 2013 00:30:30
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.69 kb
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <queue>
#include <limits.h>

using namespace std;

int n,m,e;

//the pairs of set U (values are the nodes from set V)
int pair1[10001];

//the pairs of set V (values are nodes from U)
int pair2[10001];

int dist[10001];

vector<int> adjacencyList[10001];

int bfs(){

    queue<int> q;
    for (int i=1; i<=n; i++){
        // if its a free node
        if (pair1[i] == 0){
            q.push(i);
            dist[i] = 0;
        } else {
            dist[i] = -1;
        }
    }

    int foundLengthOfMinAugmentedTree = INT_MAX;

    while (!q.empty()){
        int currentNode = q.front();
        q.pop();

        if (foundLengthOfMinAugmentedTree > dist[currentNode]){
            for (int i=0; i<adjacencyList[currentNode].size(); i++){
                int v = adjacencyList[currentNode][i];

                if (pair2[v] == 0){
                    foundLengthOfMinAugmentedTree = dist[currentNode] + 1;
                } else {
                    //if not seen yet
                    if (dist[pair2[v]] == -1){
                        dist[pair2[v]] = dist[currentNode] + 1;
                        q.push(pair2[v]);
                    }
                }
            }
        }
    }


    return foundLengthOfMinAugmentedTree != INT_MAX; // meaning that there is an augmented tree
}


int dfs(int currentNode){

    for (int i=0; i<adjacencyList[currentNode].size(); i++){
        int v = adjacencyList[currentNode][i];

        if (pair2[v] == 0){
            pair2[v] = currentNode;
            pair1[currentNode] = v;
            return 1;
        }

        else if (dist[pair2[v]] == dist[currentNode]+1){

            if (dfs(pair2[v])){
                pair2[v] = currentNode;
                pair1[currentNode] = v;
                return 1;
            }
        }
    }

    return 0;
}


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

    scanf("%d %d %d", &n, &m, &e);

    int u,v;
    for (int i=0; i<e; i++){
        scanf("%d %d", &u, &v);
        adjacencyList[u].push_back(v);
    }

    int couplingsNr = 0;

    while (bfs()){
        for (int i=1; i<=n; i++){
            if (pair1[i] == 0){
                // it is a free vertex and we try to find out if it leads to an augmenting path
                if (dfs(i)){
                    couplingsNr++;
                }
            }
        }
    }

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

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

    return 0;
}