Cod sursa(job #1943181)

Utilizator MithrilBratu Andrei Mithril Data 28 martie 2017 13:29:43
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.62 kb
#include <bits/stdc++.h>
#define NMAX 20005
using namespace std;

///OC Hasmasean Dragos
ifstream f("cuplaj.in");
ofstream g("cuplaj.out");

vector <int> graf[NMAX];
bitset<NMAX> vizitat;
int dreapta[NMAX]; /// dreapta[i] = nodul din multimea dreapta (a 2-a) cu care este cuplat nodul i;
int stanga[NMAX]; /// stanga[i] = nodul din multimea stanga (prima) cu care este cuplat nodul i;
int n,m,e,sol;

bool cupleaza(int nod) {
    /// cuplam cat putem incepand din nodul "nod" (greedy) , 1 cand am cuplat ceva , 0 cand nu am cuplat nimic
    int i,vecini;
    if(vizitat[nod]) return 0;

    vizitat[nod]=1;

    for(auto q:graf[nod]) {
        if (stanga[q]==0 || cupleaza(stanga[q])) {
        /// chestia asta ne va duce recursiv prin tot graful , cupland cat de mult putem
            dreapta[nod]=q;
            stanga[q]=nod;
            return 1;
        }
    }

    return 0;
}

void solve() {

    int i,nr_cuplaje=1;
    while (nr_cuplaje>0) {/// cuplam pana nu mai putem cupla (greedy)
        nr_cuplaje=0;
        vizitat.reset();
        for (i=1;i<=n;i++) { /// incercam sa cuplam nodurile din partea stanga cu cele din partea dreapta
            if (dreapta[i]==0)
             if (cupleaza(i)) nr_cuplaje++;
        }
    }
}

int main() {
    int i,x,y;
    f>>n>>m>>e;
    for (i=1;i<=e;i++) {
        f>>x>>y;
        graf[x].push_back(y+n);
        graf[y+n].push_back(x);
    }

    solve();

    for (i=1;i<=n;i++)
     if (dreapta[i])
      sol++;

    g<<sol<<'\n';

    for (i=1;i<=n;i++)
     if (dreapta[i])
      g<<i<<" "<<dreapta[i]-n<<'\n';

    return 0;
}