Cod sursa(job #309934)

Utilizator sandyxpSanduleac Dan sandyxp Data 1 mai 2009 14:26:35
Problema Cc Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.73 kb
#include <fstream>
#include <cstring>
#include <queue>
#include <cassert>
using namespace std;

#define NUME "cc"
ifstream fi(NUME".in");
ofstream fo(NUME".out");
#define MAXN 210
#define INF 0x3f3f3f3f

int G[MAXN][MAXN], N, S, D;
int F[MAXN][MAXN], C[MAXN][MAXN];
int Dist[MAXN], T[MAXN], U[MAXN], inque[MAXN];

#define avail(i, j) (C[i][j] - F[i][j])

int bellman(int S, int D)
{
    memset(Dist, INF, sizeof(T));
    memset(U, 0, sizeof(T));
    memset(inque, 0, sizeof(T));

    queue<int> Q;
    Q.push(S);
    Dist[S] = 0;
    while (!Q.empty()) {
        int x = Q.front();
        U[x] ++;
        Q.pop(); inque[x] = 0;
        if (U[x] == N) // ciclu
            return INF;
        for (int i = 0; i <= 2*N+1; ++i) {
            if (!C[x][i]) continue;
            if (avail(x, i) > 0 && Dist[i] > Dist[x] + G[x][i]) {
                Dist[i] = Dist[x] + G[x][i];
                T[i] = x;
                if (inque[i] == 0)
                    inque[i] = 1, Q.push(i);
            }
        }
    }
    return Dist[D];
}

void fmcm()
{
    int f, c, r, dist, i;
    for (f = c = 0; (dist = bellman(S, D)) != INF; f += r, c += r*dist) {
        r = INF;
        for (i = D; i != S; i = T[i])
            r = min(r, avail(T[i], i));
        for (i = D; i != S; i = T[i])
            F[ T[i] ][i] += r, F[i][ T[i] ] -= r;
    }
    // Problema precizeaza ca trebuie sa pot conecta toate calculatoarele
    assert(f == N);
    fo << c << "\n";
}

int main()
{
    int i, j;
    fi >> N;
    S = 0; D = 2*N + 1;

    for (i = 1; i <= N; ++i) {
        C[S][i] = N;
        C[N+i][D] = N;
        for (j = 1; j <= N; ++j) {
            fi >> G[i][N+j];
            G[N+j][i] = - G[i][N+j];
            C[i][N+j] = 1;
        }
    }
    fmcm();
    return 0;
}