Cod sursa(job #996330)

Utilizator BeilandArnoldArnold Beiland BeilandArnold Data 11 septembrie 2013 17:22:39
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp 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';
}