Cod sursa(job #1405084)

Utilizator PhilipDumitruPhilip Dumitru PhilipDumitru Data 28 martie 2015 20:29:40
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.63 kb
#include <fstream>
#include <vector>
#include <queue>

#define INF 0x70000000

using namespace std;

int nLeft, nRight, n;

int pairedWith[20002];
int dist[20002];
vector<int> adjacence[20002];

queue<int> q;

bool canMakePair()
{
    vector<int>::iterator it, it_end;
    for (int i = 1; i <= nLeft; ++i)
    {
        if (pairedWith[i]) {
            dist[i] = INF;
        } else {
            dist[i] = 0;
            q.push(i);
        }
    }
    dist[0] = INF;
    int i;
    while (!q.empty())
    {
        i = q.front();
        q.pop();
        if (dist[i] < dist[0])
        {
            for (it = adjacence[i].begin(), it_end = adjacence[i].end(); it != it_end; ++it)
            {
                if (dist[pairedWith[*it]] == INF)
                {
                    dist[pairedWith[*it]] = dist[i] + 1;
                    q.push(pairedWith[*it]);
                }
            }
        }
    }
    return dist[0] != INF;
}

bool pairNodes(int i)
{
    vector<int>::iterator it, it_end;
    if (i)
    {
        for (it = adjacence[i].begin(), it_end = adjacence[i].end(); it != it_end; ++it)
        {
            if (dist[pairedWith[*it]] == dist[i] + 1)
            {
                if (pairNodes(pairedWith[*it]))
                {
                    pairedWith[i] = *it;
                    pairedWith[*it] = i;
                    return true;
                }
            }
        }
        dist[i] = INF;
        return false;
    }
    return true;
}

int main()
{
    FILE *fin = fopen ("cuplaj.in", "r");
    FILE *fout = fopen ("cuplaj.out", "w");

    long edges, i, j, pairsNo = 0;
    // e, retE;
    fscanf(fin, "%d %d %ld", &nLeft, &nRight, &edges);
    n = nLeft + nRight;
    //e.capacity = 1;
    //retE.capacity = 0;

    while (edges--)
    {
        fscanf(fin, "%d %d", &i, &j);
        j += nLeft;
        adjacence[i].push_back(j);
        adjacence[j].push_back(i);
    }
    /*retE.to = 0;
    for (e.to = 1; e.to <= nLeft; ++i)
    {
        adjacence[0].push_back(e);
        adjacence[e.to].push_back(retE);
    }
    e.to = n;
    for (retE.to = nLeft+1; retE.to < n; ++i)
    {
        adjacence[retE.to].push_back(e);
        adjacence[e.to].push_back(retE);
    }*/


    while (canMakePair())
    {
        for (i = 1; i <= nLeft; ++i)
        {
            if (!pairedWith[i])
            {
                if (pairNodes(i))
                    ++pairsNo;
            }
        }
    }
    fprintf(fout, "%ld\n", pairsNo);
    for (i = 1; i <= nLeft; ++i)
    {
        if (pairedWith[i])
        {
            fprintf(fout, "%ld %d\n", i, pairedWith[i] - nLeft);
        }
    }

    fclose(fin);
    fclose(fout);
    return 0;
}