Cod sursa(job #1853854)

Utilizator andreiudilaUdila Andrei andreiudila Data 22 ianuarie 2017 10:23:05
Problema Cuplaj maxim in graf bipartit Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 2.36 kb
#include <stdio.h>
#include <fstream>
#include <vector>
#include <cstring>
#include <unordered_map>


using namespace std;
//ifstream cin("cuplaj.in");
ofstream cout("cuplaj.out");

struct celula{

int nod;
celula *next;
}*g[20001],*a;
int n,m,x,y,cost,i,flow,e;
unordered_map <int, int> c[20005];
int t[20001],q[20001];
bool viz[20001];

void update()
{
    int mini=2000000000;
    int aux=n+m+1;

    while(aux>0)
    {
        mini=min(mini,c[t[aux]][aux]);
        aux=t[aux];
    }

    flow+=mini;
    aux=n+m+1;

    while(aux>0)
    {
        c[t[aux]][aux]-=mini;
        c[aux][t[aux]]+=mini;
        aux=t[aux];
    }

}
bool bfs()
{
    q[1]=0;
    int l=1, r=1;
    int nod=0;
    int ok=0;

    memset(viz,0,sizeof(viz));
    viz[0]=1;

    while(l<=r)
    {
        nod=q[l];
        l++;

        for(celula *p=g[nod]; p!=NULL; p=p->next)
        {
            if(viz[p->nod]==0 && c[nod][p->nod]>0)
            {
                t[p->nod]=nod;
                if(p->nod==n+m+1) update(), ok=1;
                else
                q[++r]=p->nod, viz[p->nod]=1;
            }
        }
    }

    return ok;

}
int main()
{
    freopen("cuplaj.in", "r", stdin);

    //cin>>n>>m>>e;
    scanf("%d%d%d", &n,&m,&e);

    for(i=1;i<=e;++i)
    {
        scanf("%d%d", &x, &y);
       // cin>>x>>y;
        y+=n;

        c[x][y]=1;
        c[y][x]=0;

        a=new celula;
        a->nod=x;
        a->next=g[y];
        g[y]=a;

        a=new celula;
        a->nod=y;
        a->next=g[x];
        g[x]=a;

    }

    for(i=1;i<=n;++i)
    {
        a=new celula;
        a->nod=0;
        a->next=g[i];
        g[i]=a;

        a=new celula;
        a->nod=i;
        a->next=g[0];
        g[0]=a;

        c[0][i]=1;
        c[i][0]=0;
    }

    for(i=n+1;i<=n+m;++i)
    {
        a=new celula;
        a->nod=i;
        a->next=g[n+m+1];
        g[n+m+1]=a;

        a=new celula;
        a->nod=n+m+1;
        a->next=g[i];
        g[i]=a;

        c[i][n+m+1]=1;
        c[n+m+1][i]=0;
    }



    while(bfs())
    {

    }

    cout<<flow<<"\n";

    for(i=1;i<=n;++i)
    {
        for(celula *p=g[i]; p; p=p->next)
        {
            if(p->nod!=0 && c[i][p->nod]==0) cout<<i<<" "<<p->nod-n<<"\n";
        }
    }

    return 0;
}