Cod sursa(job #1539797)

Utilizator BogdanisarBurcea Bogdan Madalin Bogdanisar Data 1 decembrie 2015 16:59:35
Problema Cuplaj maxim in graf bipartit Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 3.81 kb
#include<iostream>
#include<fstream>
#include<vector>
#include<queue>
#include<bitset>

#define pb push_back
#define Nmax 20050
#define sursa 20005
#define dest 20006
#define INF 11

using namespace std;
ifstream f("cuplaj.in");
ofstream g("cuplaj.out");
int N,N1,N2,M;
bitset<Nmax> verif;

struct elem {
    int d=-1,cap,flow;
    elem *invers;
};
#define elemp elem*
vector<elemp> v[Nmax];
elemp muchie_from_dad[Nmax];
//elem* muchie_to_dest[Nmax];

bool bfs();

int main()
{
    f>>N1>>N2>>M;
    for (int i=1;i<=M;++i) {
        int x,y;
        f>>x>>y;
        elem *da1=new elem;
        elem *da2=new elem;
        da1->d=N1+y;
        da1->cap=1;
        da1->flow=0;
        v[x].pb(da1);

        da2->d=x;
        da2->cap=da2->flow=0;
        v[N1+y].pb(da2);

        v[x][v[x].size()-1]->invers=v[N1+y][v[N1+y].size()-1];
        v[N1+y][v[N1+y].size()-1]->invers=v[x][v[x].size()-1];
    }
    for (int i=1;i<=N1;++i) {
        elem *da=new elem;
        elem *daS=new elem;
        da->d=i;
        da->cap=1;
        da->flow=0;
        v[sursa].pb(da);

        daS->d=sursa;
        daS->cap=daS->flow=0;
        v[i].pb(daS);

        v[sursa][v[sursa].size()-1]->invers=v[i][v[i].size()-1];
        v[i][v[i].size()-1]->invers=v[sursa][v[sursa].size()-1];
    }
    for (int i=N1+1;i<=N1+N2;++i) {
        elem *da=new elem;
        elem *daD=new elem;;
        da->d=i;
        da->cap=da->flow=0;
        v[dest].pb(da);

        daD->d=dest;
        daD->cap=1;
        daD->flow=0;
        v[i].pb(daD);

        v[dest][v[dest].size()-1]->invers=v[i][v[i].size()-1];
        v[i][v[i].size()-1]->invers=v[dest][v[dest].size()-1];
    }
    int cuplaj=0;
    while (bfs()) {
        //cout<<muchie_from_dad[6]->invers->d;
        //break;
        vector<elemp>::iterator it;
        for (it=v[dest].begin();it<v[dest].end();++it) {
            elem *muchie=(*it)->invers;
            if (verif.test((*it)->d) && muchie->cap!=muchie->flow) {
                muchie_from_dad[dest]=muchie;
                int min1=INF;
                for (elem *p=muchie_from_dad[dest];  ;p=muchie_from_dad[(p->invers)->d]) {
                    if ((p->cap)-(p->flow)<min1) {
                        min1=(p->cap)-(p->flow);
                    }
                    if (((p->invers)->d)==sursa) {
                        break;
                    }
                }
                if (min1!=0) {
                    ++cuplaj;
                    for (elem *p=muchie_from_dad[dest];  ;p=muchie_from_dad[(p->invers)->d]) {
                        p->flow++;(p->invers)->flow--;
                        //cout<<((p->invers)->d)<<' ';
                        //cout<<( ( (muchie_from_dad[((p->invers)->d)])->invers )->d );
                        if (((p->invers)->d)==sursa) {
                            break;
                        }
                    }
                    //cout<<'\n';
                }
            }
        }
    }
    g<<cuplaj<<'\n';
    for (int i=1;i<=N1;++i) {
        vector<elem*>::iterator it;
        for (it=v[i].begin();it<v[i].end();++it) {
            if ((*it)->flow==1) {
                g<<i<<' '<<((*it)->d)-N1<<'\n';
            }
        }
    }
}

bool bfs() {
    verif.reset();
    queue<int> Q;
    Q.push(sursa);
    verif.set(sursa,1);
    while (!Q.empty()) {
        int nod=Q.front();
        //cout<<nod<<'\n';
        Q.pop();
        if (nod==dest) {
            return 1;
        }
        for (int k=0;k<v[nod].size();++k) {
            if (!verif.test(v[nod][k]->d) && v[nod][k]->cap!=v[nod][k]->flow) {
                muchie_from_dad[v[nod][k]->d]=v[nod][k];
                Q.push(v[nod][k]->d);
                verif.set(v[nod][k]->d,1);
            }
        }
    }
    return 0;
}