Cod sursa(job #1936463)

Utilizator MithrilBratu Andrei Mithril Data 23 martie 2017 09:31:06
Problema Cuplaj maxim in graf bipartit Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 2.13 kb
#include <bits/stdc++.h>
#define NMAX 205
#define INF 0x3f3f3f3f
#define mp make_pair
#define pb push_back
using namespace std;

ifstream fin("cuplaj.in");
ofstream fout("cuplaj.out");
typedef pair<int,int> wow;

struct myHash {
public:
    size_t operator()(const std::pair<int,int> &wow) const {
        return hash<int>()(wow.first)^hash<int>()(wow.second);
    }
};

int cardLeft,cardRight,m;
unordered_map<wow,short,myHash> f;
unordered_map<wow,short,myHash> c;
int parent[NMAX];
vector<int> g[NMAX];
bitset<NMAX> viz;
int s,t;

bool bfs() {

    viz.reset();
    memset(parent,0,sizeof(parent));
    queue<int> Q;

    Q.push(1);
    viz[1]=1;

    for(;Q.size();Q.pop()) {
        int nod=Q.front();

        for(auto q:g[nod]) {
            if(viz[q]||c[mp(nod,q)]==f[mp(nod,q)]) continue;
            viz[q]=1;
            Q.push(q);
            parent[q]=nod;
        }
    }
    return viz[t];
}

int main()
{
    fin>>cardLeft>>cardRight>>m;
    s=1,t=1+cardLeft+cardRight+1;

    for(int i=1;i<=m;i++) {
        int x,y;
        fin>>x>>y;
        x=x+1;
        y=y+cardLeft+1;
        g[x].pb(y);
        g[y].pb(x);
        c[mp(x,y)]=1;
    }

    for(int i=1;i<=cardLeft;i++) {
        c[mp(s,i+1)]=1;
        g[s].pb(i+1);
        g[i+1].pb(s);
    }

    for(int i=1;i<=cardRight;i++) {
        c[mp(i+cardLeft+1,t)]=1;
        g[t].pb(i+cardLeft+1);
        g[i+cardLeft+1].pb(t);
    }

    int flux=0,fluxMin=0;

    for(;bfs();) for(auto q:g[t]) {
        if(!viz[q]||f[mp(q,t)]==c[mp(q,t)]) continue;
        fluxMin=INF;
        parent[t]=q;

        for(q=t;q!=1;q=parent[q])
            fluxMin=min(fluxMin,c[mp(parent[q],q)]-f[mp(parent[q],q)]);

        for(q=t;q!=1;q=parent[q]) {
            f[mp(parent[q],q)]+=fluxMin;
            f[mp(q,parent[q])]-=fluxMin;
        }

        flux+=fluxMin;
    }

    fout<<flux<<'\n';
    for(int i=2;i<=cardLeft+1;i++) {
        for(auto q:g[i]) {
            if(q==s) continue;
            if(f[mp(i,q)]) {
                fout<<i-1<<' '<<q-cardLeft-1<<'\n';
            }
        }
    }
    return 0;
}