Cod sursa(job #190386)

Utilizator stef2nStefan Istrate stef2n Data 21 mai 2008 21:09:28
Problema Cc Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.48 kb
#include <fstream>
#include <vector>
#include <queue>
using namespace std;

const int MAX_N = 100;
const int INF = 1000000000;

ifstream in("cc.in");
ofstream out("cc.out");

int N;
vector <int> G[2 * MAX_N + 2];
int cost[2 * MAX_N + 2][2 * MAX_N + 2];
short int cap[2 * MAX_N + 2][2 * MAX_N + 2];
bool visited[2 * MAX_N + 2], in_queue[2 * MAX_N + 2];
int prec[2 * MAX_N + 2];
int C[2 * MAX_N + 2];

void init() {
    in >> N;
    for(int i = 1; i <= N; ++i) {
        G[0].push_back(i); G[i].push_back(0);
        cost[0][i] = cost[i][0] = 0;
        cap[0][i] = 1; cap[i][0] = 0;
    }
    for(int i = 1; i <= N; ++i)
        for(int j = N + 1; j <= 2 * N; ++j) {
            G[i].push_back(j); G[j].push_back(i);
            in >> cost[i][j]; cost[j][i] = -cost[i][j];
            cap[i][j] = 1; cap[j][i] = 0;
        }
    for(int i = N + 1; i <= 2 * N; ++i) {
        G[i].push_back(2 * N + 1); G[2 * N + 1].push_back(i);
        cost[i][2 * N + 1] = cost[2 * N + 1][i] = 0;
        cap[i][2 * N + 1] = 1; cap[2 * N + 1][i] = 0;
    }
}

void BellmanFord() {
    memset(visited, 0, (2 * N + 2) * sizeof(bool));
    visited[0] = true;
    prec[0] = -1;
    memset(in_queue, 0, (2 * N + 2) * sizeof(bool));
    in_queue[0] = true;
    C[0] = 0;
    for(int i = 1; i < 2 * N + 2; ++i)
        C[i] = INF;

    queue <int> Q;
    Q.push(0);
    while(!Q.empty()) {
        int v = Q.front();
        Q.pop();
        for(vector <int> :: iterator it = G[v].begin(); it != G[v].end(); ++it)
            if(cap[v][*it] && C[*it] > C[v] + cost[v][*it]) {
                visited[*it] = true;
                prec[*it] = v;
                C[*it] = C[v] + cost[v][*it];
                if(!in_queue[*it]) {
                    in_queue[*it] = true;
                    Q.push(*it);
                }
            }
        in_queue[v] = false;
    }
}

void max_flow() {
    do {
        BellmanFord();
        if(visited[2 * N + 1]) {
            int u = prec[2 * N + 1], v = 2 * N + 1;
            while(u != -1) {
                cap[u][v] = 0, cap[v][u] = 1;
                u = prec[u];
                v = prec[v];
            }
        }
    } while(visited[2 * N + 1]);
}

int min_cost() {
    int c = 0;
    for(int i = 1; i <= N; ++i)
        for(int j = N + 1; j <= 2 * N; ++j)
            if(!cap[i][j])
                c += cost[i][j];
    return c;
}


int main() {
    init();
    max_flow();
    out << min_cost();
    return 0;
}