Cod sursa(job #2761646)

Utilizator BeilandArnoldArnold Beiland BeilandArnold Data 3 iulie 2021 08:16:29
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2 kb
#include <fstream>

#include <vector>

#include <list>

#include <queue>

#include <limits>



typedef std::vector<unsigned> VU_t;

typedef std::list<unsigned> LU_t;

typedef std::vector<LU_t> VLU_t;



const unsigned INF = std::numeric_limits<unsigned>::max();



bool BFS(const VLU_t &Adj,const VU_t &LeftPair,const VU_t &RightPair, VU_t &Dist){

    std::queue<unsigned> Q;



    for(unsigned v=1;v<Adj.size();++v)

        if(RightPair[v]==0){

            Dist[v]=0;

            Q.push(v);

        }

        else Dist[v]=INF;

    Dist[0]=INF;



    while(!Q.empty()){

        unsigned v=Q.front(); Q.pop();

        if(Dist[v]<Dist[0])

            for(LU_t::const_iterator u=Adj[v].begin();u!=Adj[v].end();++u)

                if(Dist[LeftPair[*u]]==INF){

                    Dist[LeftPair[*u]]=Dist[v]+1;

                    Q.push(LeftPair[*u]);

                }

    }



    return Dist[0]!=INF;

}



bool DFS(unsigned v, const VLU_t &Adj, VU_t &LeftPair, VU_t &RightPair, VU_t &Dist){

    if(v!=0){

        for(LU_t::const_iterator u=Adj[v].begin();u!=Adj[v].end();++u)

            if(Dist[LeftPair[*u]]==Dist[v]+1)

                if(DFS(LeftPair[*u],Adj,LeftPair,RightPair,Dist)){

                    LeftPair[*u]=v;

                    RightPair[v]=*u;

                    return true;

                }

        Dist[v]=INF;

        return false;

    }

    return true;

}



int main(){

    std::ifstream fin("cuplaj.in");

    std::ofstream fout("cuplaj.out");



    unsigned N,M,E;

    fin>>N>>M>>E;



    VLU_t Adj(N+1);

    for(unsigned i=-0;i<E;++i){unsigned x,y; fin>>x>>y; Adj[x].push_back(y);}



    unsigned matching=0;

    VU_t RightPair(N+1,0),LeftPair(M+1,0),Dist(N+1);



    while(BFS(Adj,LeftPair,RightPair,Dist))

        for(unsigned i=1;i<=N;++i)

            if(RightPair[i]==0)

                if(DFS(i,Adj,LeftPair,RightPair,Dist))

                    ++matching;



    fout<<matching<<'\n';

    for(unsigned i=1;i<=N;++i) if(RightPair[i]!=0) fout<<i<<' '<<RightPair[i]<<'\n';

}