Cod sursa(job #770700)

Utilizator igsifvevc avb igsi Data 23 iulie 2012 17:34:49
Problema Cuplaj maxim in graf bipartit Scor 14
Compilator c Status done
Runda Arhiva educationala Marime 2.63 kb
#include <stdio.h>
#include <stdlib.h>
#include<string.h>

struct list{
    int v;
    struct list *n;
} *RG[20005];
/*matching, tree, used, queue*/
int M[10001], T[20005], Q[20005];
short F[20005][20005];
/*total # of nodes, # first set, # second set*/
int N, L, R;
/*source, destination*/
int S, D;

int path()
{
    int l, r;
    struct list *p;
    memset(T, 0, sizeof(T));

    Q[0] = S; T[S] = -1;
    l = r = 0;

    for(; l <= r; ++l)
    {
        if(Q[l] == D) continue;
        for(p = RG[ Q[l] ]; p; p = p->n)
            if(!T[p->v] && F[ Q[l] ][p->v] < 1)
            {
                T[p->v] = Q[l] ;
                Q[++r] = p->v;
            }
    }

    return T[D];
}

int main()
{
    int e, a, b, i, flow, maxFlow = 0;
    struct list *p;
    FILE *out = fopen("cuplaj.out", "w");
    FILE *in = fopen("cuplaj.in", "r");

    fscanf(in, "%d %d %d", &L, &R, &e);

    N = L + R + 2;
    for(i = 1; i <= L; ++i)
    {
        p = malloc(sizeof(struct list));
        p->v = i;
        p->n = RG[N-1];
        RG[N-1] = p;

        p = malloc(sizeof(struct list));
        p->v = N-1;
        p->n = RG[i];
        RG[i] = p;
    }
    for(i = L+1; i <= L+R; ++i)
    {
        p = malloc(sizeof(struct list));
        p->v = N;
        p->n = RG[i];
        RG[i] = p;

        p = malloc(sizeof(struct list));
        p->v = i;
        p->n = RG[N];
        RG[N] = p;
    }

    for(; e; --e)
    {
            fscanf(in, "%d %d", &a, &b);
            p = malloc(sizeof(struct list));
            p->v = b + L;
            p->n = RG[a];
            RG[a] = p;

            p = malloc(sizeof(struct list));
            p->v = a;
            p->n = RG[b + L];
            RG[b + L] = p;
    }

    S = N-1;
    D = N;

    while( path() )
        for(p = RG[N]; p; p = p->n)
        {
            if(p->v == S || !T[p->v] || F[p->v][N] == 1) continue;

            flow = 1 - F[p->v][N];
            for(i = p->v; i != S; i = T[i])
                if(flow > 1 - F[T[i]][i])
                    flow = 1 - F[T[i]][i];

            if(flow == 0) continue;

            F[p->v][N] += flow;
            F[N][p->v] -= flow;
            for(i = p->v; i != S; i = T[i])
            {
                F[T[i]][i] += flow;
                F[i][T[i]] -= flow;
            }
            maxFlow += flow;
        }

    fprintf(out, "%d\n", maxFlow);
    for(i = 1; i <= L; ++i)
        for(a = 1; a <= R; ++a)
            if(F[i][a + L] == 1 || F[a + L][i] == 1)
                fprintf(out, "%d %d\n", i, a);

    fclose(in);
    fclose(out);
    return 0;
}