Cod sursa(job #1786692)

Utilizator akaprosAna Kapros akapros Data 23 octombrie 2016 14:49:13
Problema Cc Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.28 kb
#include <bits/stdc++.h>
#define maxN 104
#define maxE 50002
#define inf 1 << 30
using namespace std;
int N, len, ans, G[maxN][maxN], l[maxN], r[maxN];
int p[maxN], cr[maxN], cc[maxN], vr[maxN], vc[maxN];
int Min;
bool ok;

FILE *fin = freopen("cc.in", "r", stdin);
FILE *fout = freopen("cc.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 <= N; ++ 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 <= N; ++ j)
        if (!cc[j])
            vc[j] += Min;

    for (i = 1; i <= N; ++ i)
        if (!cr[i])
            for (j = 1; j <= N; ++ 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 read()
{
    int i, j;

    scanf("%d", &N);
    ///init();
    for (i = 1; i <= N; ++ i)
        for (j = 1; j <= N; ++ j)
            scanf("%d", &G[i][j]);

}
void solve()
{
    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])
            ans += G[i][r[i]];
    printf("%d\n", ans);
}

int main()
{
    read();
    solve();
    write();
    return 0;
}