Cod sursa(job #774260)

Utilizator igsifvevc avb igsi Data 3 august 2012 23:15:29
Problema Cuplaj maxim de cost minim Scor 50
Compilator c Status done
Runda Arhiva educationala Marime 3.21 kb
#include <stdlib.h>
#include <stdio.h>
#define maxn 610
#define maxe 50000
#define INF 2000000000

struct list { int v; struct list *n; } *G[maxn];
int edge[maxe][2], E, N, L, R, source, sink, sol[maxn], nre;
int cap[maxn][maxn], cost[maxn][maxn];
int Q[2][maxn], inQ[maxn], T[maxn];
int D[maxn], flow[maxn][maxn];

int bellmanford () ;
void read ();

int main()
{
    int f, mc, i;
    FILE *out = fopen("cmcm.out", "w");

    read ();
    mc = 0;
    while (bellmanford())
    {
        f = INF;
        for (i = sink; i != source; i = T[i])
            if (cap[T[i]][i] - flow[T[i]][i] < f)
                f = cap[T[i]][i] - flow[T[i]][i];

        for (i = sink; i != source; i = T[i])
        {
            flow[T[i]][i] += f;
            flow[i][T[i]] -= f;
        }
        mc += f * D[sink];
    }

    for(i = 0; i < E; ++i)
        if (cost[edge[i][0]][L+edge[i][1]] && flow[edge[i][0]][L+edge[i][1]] == 1)
            sol[++nre] = i+1;

    fprintf (out, "%d %d\n", nre, mc);
    for(i = 1; i <= nre; i++)
        fprintf(out, "%d ", sol[i]);
    fprintf(out, "\n");

    fclose(out);
    return 0;
}

int bellmanford()
{
    int i, j, choose, node, ok;
    struct list *p;

    for (i = 0; i <= N; ++i)
    {
        D[i] = INF;
        inQ[i] = 0;
        T[i] = -1;
    }

    Q[0][0] = 1;
    Q[0][1] = source;
    D[source] = 0;
    choose = 0;

    for (ok = i = 1; i <= N && ok; ++i)
    {
        Q[1-choose][0] = 0;

        for (ok = 0, j = 1; j <= Q[choose][0]; ++j)
        {
            node = Q[choose][j];
            for (p = G[node]; p; p = p->n)
                if (cap[node][p->v] > flow[node][p->v] && D[p->v] > D[node] + cost[node][p->v])
                {
                    ok = 1;
                    D[p->v] = D[node] + cost[node][p->v];
                    T[p->v] = node;
                    if (inQ[p->v] != i)
                    {
                        Q[1-choose][ ++Q[1-choose][0] ] = p->v;
                        inQ[p->v] = i;
                    }
                }
        }
        choose = 1 - choose;
    }
    return (T[sink] != -1);
}

void read ()
{
    FILE *in = fopen("cmcm.in", "r");
    int a, b, c, i;
    struct list *p;

    fscanf (in, "%d %d %d", &L, &R, &E);
    N = R + L + 1;
    source = 0;
    sink = N;

    for(i = 0; i < E; ++i)
    {
        fscanf (in, "%d %d %d", &a, &b, &c);
        edge[i][0] = a; edge[i][1] = b;
        b += L;
        cap[a][b] = 1; cost[a][b] = c; cost[b][a] = -c;

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

    for (i = 1; i <= L; ++i)
    {
        cap[source][i] = 1;
        p = malloc(sizeof(struct list));
        p->v = i; p->n = G[source]; G[source] = p;
        p = malloc(sizeof(struct list));
        p->v = source; p->n = G[i]; G[i] = p;
    }

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

    fclose (in);
}