Cod sursa(job #2958438)

Utilizator maria.neagaNeaga-Budoiu Maria maria.neaga Data 26 decembrie 2022 16:51:43
Problema Cuplaj maxim in graf bipartit Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.91 kb
#include <iostream>
#include <fstream>
#include <math.h>
#include <queue>

#define MAX 110000

using namespace std;

ifstream in("cuplaj.in");
ofstream out("cuplaj.out");

/*
Idee: creez reteaua de transport asociata grafului si calculez fluxul maxim (= cuplajul maxim) -> Edmonds-Karp
Afisez muchiile pe care fluxul final e 1
*/
int n, m, e;
pair<int, int> muchie[10001][10001]; //fluxul si capacitatile pe muchii
vector<int> tata; //vectorul de tati
vector<int> l[10001]; //lista muchiilor
vector<int> cc; //capacitatea ramasa la mom. curent

int bfs(int s, int t)
{
    queue <int> q;

    //la fiecare parcurgere modificam vectorul de tati si capacitatile ramase
    for(int i=0; i<=n+m+1; i++)
    {
        tata[i] = -1;
        cc[i] = 0;
    }

    cc[s] = MAX; //capacitatea ramasa in sursa e maxima
    q.push(s);

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

        for(int i=0; i<l[nod].size(); i++)
        {
            int nodNou = l[nod][i];
            if(tata[nodNou] == -1) //daca nodul curent nu a fost parcurs
            {
                //actualizez capaciatea curenta cu cea minima pe lant
                if(muchie[nod][nodNou].second - muchie[nod][nodNou].first > 0)
                {
                    tata[nodNou] = nod;
                    cc[nodNou] = min(cc[nod], muchie[nod][nodNou].second - muchie[nod][nodNou].first);

                    if(nodNou == t)
                        return cc[t];

                    q.push(nodNou);
                }
            }
        }
    }
    return 0;
}

int fluxMax(int s, int t)
{
    int rez = 0;

    int flux = bfs(s, t);

    while(flux != 0)
    {
        rez += flux;
        int nod = t;
        while(nod != s) //revizuiesc fluxul
        {
            int t = tata[nod];
            muchie[t][nod].first += flux;
            muchie[nod][t].first -= flux;
            nod = t;
        }

        flux = bfs(s, t);
    }

    return rez;
}
int main()
{
    in>>n>>m>>e;
    tata.resize(n+m+2);
    cc.resize(n+m+2);

    int x, y;
    for(int i=1; i<=e; i++)
    {
        cin>>x>>y;
        y = y + n; //adaug n la y ca sa il diferentiez de x
        muchie[x][y].second = 1;
        muchie[x][y].first = 0;
        muchie[0][x].second = 1;
        muchie[y][n+m+1].second = 1;

        l[x].push_back(y);
        l[y].push_back(x);
        l[0].push_back(x); //0 e nodul de start, se leaga de toate nodurile x
        l[x].push_back(0);
        l[y].push_back(n+m+1); //y se leaga de nodul de oprire, adica n+m+1
        l[n+m+1].push_back(y);
    }

    int f = fluxMax(0, n+m+1);
    out<<f<<"\n";

    for(int i=1; i<=n; i++)
    {
        for(int j=0; j<l[i].size(); j++)
        {
            int nod = l[i][j];
            if(muchie[i][nod].first == 1)
               out<<i<<" "<<nod-n<<" "<<"\n";
        }
    }
    return 0;
}