Cod sursa(job #908803)

Utilizator sebii_cSebastian Claici sebii_c Data 9 martie 2013 23:56:07
Problema Cc Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.42 kb
#include <cstdio>

#include <queue>
#include <vector>

using namespace std;

const int MAXN = 210;
const int INF = 0x3f3f3f3f;

int N;
vector<int> G[MAXN];

int cap[MAXN][MAXN];
int cost[MAXN][MAXN];
int flow[MAXN][MAXN];

bool found;

int bellman_ford()
{
    vector<int> dist(N + 2, INF);
    vector<int> prev(N + 2, -1);
    vector<bool> inqueue(N + 2, false);

    queue<int> q;
    q.push(0);
    inqueue[0] = true;
    dist[0] = 0;

    while (!q.empty()) {
        int node = q.front();
        q.pop();
        inqueue[node] = false;

        vector<int>::iterator it;
        for (it = G[node].begin(); it != G[node].end(); ++it) {
            if (cap[node][*it] - flow[node][*it] > 0 && 
                    dist[node] + cost[node][*it] < dist[*it]) {
                dist[*it] = dist[node] + cost[node][*it];
                prev[*it] = node;
                if (!inqueue[*it]) {
                    q.push(*it);
                    inqueue[*it] = true;
                }
            }
        }
    }

    if (dist[N + 1] < INF / 2) {
        found = true;

        int fmin = INF;
        for (int node = N + 1; node != 0; node = prev[node]) 
            fmin = min(fmin, cap[prev[node]][node] - flow[prev[node]][node]);
        for (int node = N + 1; node != 0; node = prev[node]) {
            flow[prev[node]][node] += fmin;
            flow[node][prev[node]] -= fmin;
        }

        return fmin * dist[N + 1];
    }

    return 0;
}

int mfmc()
{
    int res = 0;
    found = true;

    while (found) {
        found = false;
        res += bellman_ford();
    }

    return res;
}

int main()
{
    freopen("cc.in", "r", stdin);
    freopen("cc.out", "w", stdout);

    scanf("%d", &N);
    for (int i = 1; i <= N; ++i) {
        for (int j = 1; j <= N; ++j) {
            int cst;
            scanf("%d", &cst);

            G[i].push_back(N + j);
            G[N + j].push_back(i);

            cost[i][N + j] = cst;
            cost[N + j][i] = -cst;
            cap[i][N + j] = 1;
        }
    }

    for (int i = 1; i <= N; ++i) {
        G[0].push_back(i);
        G[i].push_back(0);

        cost[0][i] = 0;
        cost[i][0] = 0;
        cap[0][i] = 1;
    }

    for (int i = 1; i <= N; ++i) {
        G[i + N].push_back(2 * N + 1);
        G[2 * N + 1].push_back(i + N);

        cost[i + N][2 * N + 1] = 0;
        cost[2 * N + 1][i + N] = 0;
        cap[i + N][2 * N + 1] = 1;
    }

    N = 2 * N;
    printf("%d\n", mfmc());

    return 0;
}