Cod sursa(job #1872427)

Utilizator Coroian_DavidCoroian David Coroian_David Data 8 februarie 2017 11:15:54
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.08 kb
#include <cstdio>

#include <cstring>

using namespace std;

FILE *f, *g;

int n, m, q;

int cuplajulDreapta[10009];
int cuplajulStanga[10009];

int k;

int lst[10009];
int urm[100001];
int nod[100001];

bool cuplaj[10009];

void add(int a, int b)
{
    k ++;

    nod[k] = b;
    urm[k] = lst[a];

    lst[a] = k;
}

void readFile()
{
    f = fopen("cuplaj.in", "r");

    fscanf(f, "%d%d%d", &n, &m, &q);

    int i;
    int a, b;
    for(i = 1; i <= q; i ++)
    {
        fscanf(f, "%d%d", &a, &b);

        add(a, b);
    }

    fclose(f);
}

int rez;

bool cuplat(int n)
{
    if(cuplaj[n] == 1)
        return 0;

    cuplaj[n] = 1;

    int p;

    ///Cuplam nodul n cu primul vecin NEcuplat
    for(p = lst[n]; p != 0; p = urm[p])
    {
        if(cuplajulStanga[nod[p]] == 0)
        {
            cuplajulDreapta[n] = nod[p];
            cuplajulStanga[nod[p]] = n;

            return 1;
        }
    }

    ///Nu am reusit, incercam sa refacem cuplajul vecinului pentru al cupla cu el
    for(p = lst[n]; p != 0; p = urm[p])
    {
        ///Daca putem recupla pe vecin
        if(cuplat(cuplajulStanga[nod[p]]) == 1)
        {
            cuplajulDreapta[n] = nod[p];
            cuplajulStanga[nod[p]] = n;

            return 1;
        }
    }

    return 0;
}

void solve()
{
    int i;

    int change = 1;
    int x;

    while(change != 0)
    {
        change = 0;
        memset(cuplaj, 0, sizeof(cuplaj));

        for(i = 1; i <= n; i ++)
            if(cuplajulDreapta[i] == 0)
            {
                x = cuplat(i);

                change = change || x;
            }
    }

    for(i = 1; i <= n; i ++)
        if(cuplajulDreapta[i] != 0)
            rez ++;
}

void printFile()
{
    g = fopen("cuplaj.out", "w");

    fprintf(g, "%d\n", rez);

    int i;
    for(i = 1; i <= n; i ++)
        if(cuplajulDreapta[i] != 0)
            fprintf(g, "%d %d\n", i, cuplajulDreapta[i]);
}

int main()
{
    readFile();

    solve();

    printFile();

    return 0;
}