Cod sursa(job #1842308)

Utilizator dragos_vecerdeaVecerdea Dragos dragos_vecerdea Data 6 ianuarie 2017 19:50:31
Problema Cuplaj maxim in graf bipartit Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.35 kb
#include <stdio.h>
#include <vector>
#include <queue>
using namespace std;
#define NMAX 2000
#define MMAX 5000
const int INF = 0x7fffffff;
struct pereche{
        int st , dr;
};
pereche solutie[10000];
int N,M, NN,CN,flux=0, fluxminim, nod;
int ramas;
int c[NMAX+1][NMAX+1];
int f[NMAX+1][NMAX+1];
int tata[NMAX+1];
char vizitat[NMAX+1];
vector <int> muchie[NMAX+1];
FILE *fin = fopen("cuplaj.in", "r");
FILE *fout = fopen("cuplaj.out", "w");
int minim(int a, int b)
{
    if(a<b) return a;
    return b;
}
int bfs()
{
    for(int i=0;i<=N;i++)
    {
        vizitat[i]=0;
    }
    queue <int> frontiera;
    frontiera.push(0);
    vizitat[0]=1;
    while(!frontiera.empty())
    {
        int nod = frontiera.front();
        frontiera.pop();
        if(nod == N) continue;
        for(auto m : muchie[nod])
        {
            if(c[nod][m] == f[nod][m] || vizitat[m]==1) continue;
            tata[m] = nod;
            vizitat[m] = 1;
            frontiera.push(m);
        }
    }
    return vizitat[N];
}
int main()
{
    fscanf(fin, "%d%d%d", &N, &NN, &M);
    for(int i=1;i<=M;i++)
    {
        int x,y,z;
        fscanf(fin , "%d%d", &x, &y);
        c[x][N+y]=1;
        c[N+y][N+NN+1]=1;
        c[0][x]=1;
        muchie[x].push_back(y+N);
        muchie[N+y].push_back(x);
        muchie[0].push_back(x);
        muchie[x].push_back(0);
        muchie[N+y].push_back(N+NN+1);
        muchie[N+NN+1].push_back(y+N);
    }
    CN=N;
    N=N+NN+1;
    while(bfs())
    {
        for(auto m : muchie[N])
        {
            if(c[m][N] == f[m][N] || vizitat[m]==0 ) continue;
            tata[N] = m;
            fluxminim = INF;
            nod = N;
            while(nod != 0)
            {
                fluxminim = minim(fluxminim , c[tata[nod]][nod]-f[tata[nod]][nod]);
                nod = tata[nod];
            }
            if(fluxminim == 0) continue;
            nod = N;
            while(nod != 0)
            {
                f[tata[nod]][nod] += fluxminim;
                f[nod][tata[nod]] -= fluxminim;
                nod = tata[nod];
            }
            flux += fluxminim;
        }
    }
    fprintf(fout, "%d\n", flux);
    for(int i=1;i<=CN;i++)
        for(int j=CN+1;j<=N;j++)
    {
        if(f[i][j]==1) fprintf(fout,"%d %d\n", i,j-CN);
    }
    return 0;
}