Cod sursa(job #1435347)

Utilizator darkseekerBoaca Cosmin darkseeker Data 12 mai 2015 22:00:57
Problema Cc Scor 100
Compilator cpp Status done
Runda mixxx_phaser Marime 2.58 kb
#include <fstream>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <limits>
using namespace std;

const int MAX_N = 202;

struct edge {
    int cost, cap, v;
};

vector<int> G[MAX_N];

int cap[MAX_N][MAX_N], cost[MAX_N][MAX_N], N;

vector<int> bellman_ford(int source, int dest) {
    vector<char> in_queue(2 * N + 2, 0);
    vector<int> dist(2 * N + 2, numeric_limits<int>::max() / 2);
    vector<int> parent(2 * N + 2, -1);
    queue<int> q;

    q.push(source); dist[source] = 0; in_queue[source] = 1;

    while (!q.empty()) {
        int node = q.front();
        in_queue[node] = 0;
        q.pop();
        for (auto v : G[node]) {
            if ((dist[v] > dist[node] + cost[node][v]) && cap[node][v] > 0) {
                dist[v] = dist[node] + cost[node][v];
                parent[v] = node;
                if (!in_queue[v]) {
                    in_queue[v] = 1;
                    q.push(v);
                }
            }
        }
    }

    vector<int> path;
    for (int node = dest; node != -1; node = parent[node]) {
        path.push_back(node);
    }

    reverse(path.begin(), path.end());
    return path;
}

int saturate(const vector<int>& path) {
    if (path.size() < 2)
        return -1;

    int flow = cap[path[0]][path[1]];
    int total_cost = cost[path[0]][path[1]];

    for (int i = 1; i < path.size() - 1; ++i) {
        flow = min(flow, cap[path[i]][path[i + 1]]);
        total_cost += cost[path[i]][path[i + 1]];
    }

    for (int i = 0; i < path.size() - 1; ++i) {
        cap[path[i]][path[i + 1]] -= flow;
        cap[path[i + 1]][path[i]] += flow;
    }

    return flow * total_cost;
}

int max_flow() {
    int max_flow = 0;
    while(1) {
        vector<int> path = std::move(bellman_ford(0, 2 * N + 1));
        int flow = saturate(path);
        if (flow == -1)
            return max_flow;
        max_flow += flow;
    }
}

int main() {
    ifstream fin("cc.in");
    ofstream fout("cc.out");

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

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

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

    fout << max_flow() << endl;

    fin.close();
    fout.close();
}