Cod sursa(job #770835)

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

#define QWE 20003

struct list{
    short v;
    struct list *next;
} *ResidualGraph[QWE];
short L, R, N, maxFlow;
short Tree[QWE], Queue[QWE];
char Flow[QWE][QWE], C[QWE][QWE];
FILE *in, *out;

int path(short source, short sink);

int main()
{
    short i, a, b, source, sink, flow;
    struct list *p;

    in = fopen("cuplaj.in", "r");
    fscanf(in, "%hd %hd %hd", &L, &R, &i);
    for(; i; --i)
    {
        fscanf(in, "%hd %hd", &a, &b);
        b += L;
        C[a][b] = 1;

        p = malloc(sizeof(struct list));
        p->v = b;
        p->next = ResidualGraph[a];
        ResidualGraph[a] = p;

        p = malloc(sizeof(struct list));
        p->v = a;
        p->next = ResidualGraph[b];
        ResidualGraph[b] = p;
    }
    fclose(in);

    N = L + R + 2;
    source = N-1;
    sink = N;
    for(i = 1; i <= L; ++i)
    {
        C[source][i] = 1;
        p = malloc(sizeof(struct list));
        p->v = i;
        p->next = ResidualGraph[source];
        ResidualGraph[source] = p;
        p = malloc(sizeof(struct list));
        p->v = source;
        p->next = ResidualGraph[i];
        ResidualGraph[i] = p;
    }
    for(i = L+1; i <= N-2; ++i)
    {
        C[i][sink] = 1;
        p = malloc(sizeof(struct list));
        p->v = i;
        p->next = ResidualGraph[sink];
        ResidualGraph[sink] = p;
        p = malloc(sizeof(struct list));
        p->v = sink;
        p->next = ResidualGraph[i];
        ResidualGraph[i] = p;
    }

    while(path(source, sink))
        for(p = ResidualGraph[sink]; p; p = p->next)
        {
            if(!Tree[p->v] || Flow[p->v][sink] >= C[p->v][sink]) continue;

            flow = C[p->v][sink] - Flow[p->v][sink];
            for(i = p->v; i != source && i; i = Tree[i])
                if(flow > C[Tree[i]][i] - Flow[Tree[i]][i])
                    flow = C[Tree[i]][i] - Flow[Tree[i]][i];

            if(!flow) continue;

            Flow[p->v][sink] += flow;
            Flow[sink][p->v] -= flow;
            for(i = p->v; i != source && i; i = Tree[i])
            {
                Flow[Tree[i]][i] += flow;
                Flow[i][Tree[i]] -= flow;
            }
            maxFlow += flow;
        }

    out = fopen("cuplaj.out", "w");
    fprintf(out, "%hd\n", maxFlow);
    for(a = 1; a <= L; ++a)
        for(b = L+1; b <= N-2; ++b)
            if(Flow[a][b] == 1 || Flow[b][a] == 1)
            {
                fprintf(out, "%hd %hd\n", a, b-L);
                break;
            }
    fclose(out);
    return 0;
}

int path(short source, short sink)
{
    short l, r, node;
    struct list *p;
    memset(Tree, 0, sizeof(Tree));

    Tree[source] = -1;
    Queue[0] = source;

    for(l = r = 0; l <= r; ++l)
    {
        node = Queue[l];
        if(node == sink) continue;
        for(p = ResidualGraph[node]; p; p = p->next)
            if(!Tree[p->v] && C[node][p->v] > Flow[node][p->v])
            {
                Tree[p->v] = node;
                Queue[++r] = p->v;
            }
    }
    return Tree[sink];
}