Cod sursa(job #2961042)

Utilizator Rincu_StefaniaRincu Stefania Rincu_Stefania Data 5 ianuarie 2023 16:46:36
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.18 kb
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <cstring>
#include <fstream>

using namespace std;

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

vector<int> l[20001];
int viz[20001], gr1[20001], gr2[20001] ;
int n, m;

int matching(int val)
{
    if(viz[val])
        return 0;
    viz[val] = 1;
    for(int i = 0; i < l[val].size(); i++)
        if(!gr2[l[val][i]])
        {
            gr1[val] = l[val][i];
            gr2[l[val][i]] = val;
            return 1;
        }
    for(int i = 0; i < l[val].size(); i++)
        if(matching(gr2[l[val][i]]))
        {
            gr1[val] = l[val][i];
            gr2[l[val][i]] = val;
            return 1;
        }
    return 0;
}

int main()
{
    int n, m, e, st, fin, ok = 1, match = 0;
    in>>n>>m>>e;
    for(int i = 1; i <= e; i++)
    {
        in>>st>>fin;
        l[st].push_back(fin);
    }

    while(ok)
    {
        ok = 0;
        memset(viz, 0, sizeof(viz));
        for(int i = 1; i <= n; i++)
            if(!gr1[i])
                ok |= matching(i);
    }

    for(int i = 1; i <= n; i++)
        if(gr1[i])
            match += 1;
    out<<match<<"\n";

    for(int i = 1; i <= n; i++)
        if(gr1[i])
           out<<i<<" "<<gr1[i]<<"\n";
    return 0;
}

/*
///flow_sent -> fluxul trimis pe o muchie, capacity -> capacitatea muchiei,
int flow_sent[1005][1005], capacity[1005][1005], minim[1005];
///l -> vecorul care retine graful + graful rezidual
vector<int> l[20001];
///n -> noduri, m -> muchii
int n, m;
///vectorul de parinti
int tata[1005] = {0};

int bfs(int src, int dest)
{
    queue<int> q;
    ///rescriem valorile din vectorul de tati si cel de distante
    memset(tata, -1, sizeof(tata));
    memset(minim, 0, sizeof(minim));

    q.push(src);
    tata[src] = -2;
    minim[src] = 99999;

    ///BFS clasic
    while(!q.empty())
    {
        int u = q.front();
        q.pop();
        for(int i = 0; i < l[u].size(); i++)
        {
            int v = l[u][i];
            ///inseamna ca nu e vizitat
            if(capacity[u][v] > flow_sent[u][v] && tata[v] == -1)
            {
                ///updatam vectorul de tati pentru a avea drumul
                tata[v] = u;

                minim[v] = min(minim[u], capacity[u][v] - flow_sent[u][v]);
                ///iesim cu 1 daca am ajuns la nodul n(cel final)
                if(v == dest)
                    return minim[u];
                q.push(v);
            }
        }
    }
    return 0;
}

///pentru a optimiza programul efectuam algoritmul lui Edmonds Karp atata timp
///cat prin parcurerea BFS putem ajunge din nodul 1 in nodul n, ceea ce inseamna
///ca estista un drum pe care fluxul rezidual sa fie minim si mai am capacitate
///disponibila pe muchii pentru a mari fluxul
int max_flow(int src, int dest)
{
    ///maxim -> fluxul maxim, flow -> fluxul minim rezidual gasit dupa parcurgerea BFS
    ///u -> nodul curent, v -> vecinul acestuia
    int maxim = 0, flow, u, v;
    ///cat timp prin parcurgerea BFS ajung din nodul 1 in nodul n
    while(true)
    {
        flow = bfs(src, dest);
        if(flow == 0)
            break;
        maxim += flow;
        u = dest;
        while(u != src)
        {
            v = tata[u];
            flow_sent[v][u] += flow;
            flow_sent[u][v] -= flow;
            u = v;
        }
    }
    return maxim;
}

int main()
{
    int n, m, e, dest, src = 0, st, fin;
    in>>n>>m>>e;
    dest = n + m + 1;
    for(int i = 1; i <= n; i++)
    {
        l[0].push_back(i);
        l[i].push_back(0);
        capacity[0][i] = 1;
    }
    for(int i = 1; i <= m; i++)
    {
        l[dest].push_back(n+i);
        l[n+i].push_back(dest);
        capacity[n+i][dest] = 1;
    }
    for(int i = 1; i <= e; i++)
    {
        in>>st>>fin;
        l[st].push_back(fin+n);
        l[fin+n].push_back(st);
        capacity[st][fin+n] = 1;
    }

    out<<max_flow(src, dest)<<"\n";

    for(int i = 1; i <= n; i++)
        for(int j = n + 1; j <= n + m; j++)
            if(flow_sent[i][j])
                    out<<i<<" "<<j-n<<"\n";
    return 0;
}*/