Cod sursa(job #690992)

Utilizator andrei.finaruFinaru Andrei Emanuel andrei.finaru Data 26 februarie 2012 10:10:38
Problema Cuplaj maxim in graf bipartit Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.1 kb
#include <fstream>
#include <cstring>
#include <vector>
#include <queue>

using namespace std;

ifstream f("cuplaj.in");
ofstream g("cuplaj.out");

int n,m,t,vecin,nr_vecini,flux[20005][20005],c[20005][20005],flux_maxim,minim,x,y,tata[20005],e;
char viz[20005];
vector <int> lista[20005];
queue <int> q;

int bf()
{
    int i;
    memset(viz,0,sizeof(viz));
    memset(tata,0,sizeof(tata));
    q.push(0);
    viz[0]=1;
    while(!q.empty())
    {
        x=q.front(); q.pop();
        nr_vecini=lista[x].size();
        for(i=0;i<nr_vecini;++i)
        {
            vecin=lista[x][i];
            if(!viz[vecin]&&flux[x][vecin]<c[x][vecin])
            {
                viz[vecin]=1;
                tata[vecin]=x;
                q.push(vecin);
            }
        }
    }
    return viz[t];
}

int main()
{
    int i,j;
    f>>n>>m>>e;
    //g<<n<<m<<e<<'\n';
    t=n+m+1;
    for(i=0;i<e;++i)
    {
        f>>x>>y;
        lista[x].push_back(y+n);
        lista[y+n].push_back(x);
        c[x][y+n]=1;
    }
    for(i=1;i<=n;++i)
    {
        lista[0].push_back(i);
        lista[i].push_back(0);
        c[0][i]=1;
    }
    for(;i<t;++i)
    {
        lista[i].push_back(t);
        lista[t].push_back(i);
        c[i][t]=1;
    }
    while(bf())
        for(i=n+1;i<t;++i)
            if(tata[i]&&flux[i][t]<c[i][t])
            {
                minim=c[i][t]-flux[i][t];
                for(j=i;j;j=tata[j])
                    if(c[tata[j]][j]-flux[tata[j]][j]<minim) minim=c[tata[j]][j]-flux[tata[j]][j];
                if(minim)
                {
                    flux[i][t]+=minim;
                    flux[t][i]-=minim;
                    for(j=i;j;j=tata[j])
                    {
                        flux[tata[j]][j]+=minim;
                        flux[j][tata[j]]-=minim;
                    }
                    flux_maxim+=minim;
                }
            }
    g<<flux_maxim<<'\n';
    for(i=1;i<=n;++i)
        for(j=n+1;j<t;++j)
            if(flux[i][j]) g<<i<<' '<<j-n<<'\n';
    f.close(); g.close();
    return 0;
}