Cod sursa(job #1786684)

Utilizator akaprosAna Kapros akapros Data 23 octombrie 2016 14:37:48
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.82 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;
bool ok;

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);
    if (N > M)
    {
        ok = 1;
        swap(N, M);
    }
    init();
    for (i = 1; i <= E; ++ i)
    {
        int x, y;
        scanf("%d %d %d", &x, &y, &cost[i]);
        if (ok)
            swap(x, y);
        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 (int 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] && edge[i][r[i]])
        {
            ++ len;
            ans += cost[edge[i][r[i]]];
        }
    printf("%d %d\n", len, ans);
    for (i = 1; i <= N; ++ i)
        if (r[i] && edge[i][r[i]])
            printf("%d ", edge[i][r[i]]);
}
int main()
{
    read();
    solve();
    write();
    return 0;
}