Cod sursa(job #1786662)

Utilizator akaprosAna Kapros akapros Data 23 octombrie 2016 14:12:42
Problema Cuplaj maxim de cost minim Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 2.33 kb
#include <bits/stdc++.h>
#define maxN 304
#define maxE 50002
#define inf 1 << 30
using namespace std;
int N, M, E, len, ans, G[maxN][maxN], l[maxN], r[maxN], cost[maxE];
int edge[maxN][maxN];
int p[maxN], cr[maxN], cc[maxN], vr[maxN], vc[maxN];
int Min, cnt;

FILE *fin = freopen("cmcm.in", "r", stdin);
FILE *fout = freopen("cmcm.out", "w", stdout);

void find_zero ()
{
    int i, j, t;

    for (Min = inf, i = 1; i <= N; ++ i) if (!cr[i])
            for (j = 1; j <= M; ++ j) if (!cc[j])
                    if (Min > G[i][j] + vr[i] - vc[j])
                        Min = G[i][j] + vr[i] - vc[j];

    for (i = 1; i <= N; ++ i) if (cr[i]) vr[i] += Min;
    for (j = 1; j <= M; ++ j) if (!cc[j]) vc[j] += Min;

    for (i = 1; i <= N; ++ i) if (!cr[i])
            for (j = 1; j <= M; ++ j)if (!cc[j] && (G[i][j] + vr[i] == vc[j]))
                {
                    if (r[i])
                    {
                        p[i] = j, cr[i] = 1, cc[r[i]] = 0;
                        break;
                    }
                    else
                    {
                        do t = l[j], r[i] = j, l[j] = i, i = t, j = p[i];
                        while (t);
                        return;
                    }
                }

    find_zero ();
}
void init()
{
    int i, j;
    for (i = 1; i <= N; ++ i)
        for (j = 1; j <= M; ++ j)
            G[i][j] = inf;
}
void read()
{
    int i;

    scanf("%d %d %d", &N, &M, &E);
    init();
    for (i = 1; i <= E; ++ i)
    {
        int x, y;
        scanf("%d %d %d", &x, &y, &cost[i]);
        G[x][y] = cost[i];
        edge[x][y] = i;
    }
}
void solve()
{
    int i;

    memset (vr, 0, sizeof (vr)), memset (vc, 0, sizeof (vc));
    memset (l, 0, sizeof (l)), memset (r, 0, sizeof (r));

    for (cnt = 0; cnt < N; ++ cnt)
    {
        memset (cr, 0, sizeof (cr)), memset (p, 0, sizeof (p));
        memcpy (cc, l, sizeof (cc));
        find_zero ();
    }
}
void write()
{
    int i;
    for (i = 1; i <= N; ++ i)
        if (r[i])
        {
            ++ len;
            ans += cost[edge[i][r[i]]];
        }
    printf("%d %d\n", len, ans);
    for (i = 1; i <= N; ++ i)
        if (r[i])
            printf("%d ", edge[i][r[i]]);
}
int main()
{
    read();
    solve();
    write();
    return 0;
}