Cod sursa(job #1655323)

Utilizator depevladVlad Dumitru-Popescu depevlad Data 17 martie 2016 21:46:56
Problema Cc Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.84 kb
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>

using namespace std;

const int INF = 0x3f3f3f3f;

bool bellmanFord(const vector < vector < int > > &graph,
                 const vector < vector < int > > &cost,
                 const vector < vector < int > > &cap,
                 const vector < vector < int > > &flow,
                 vector < int > &f) {
    vector < bool > inQ(graph.size(), false);
    vector < int > dist(graph.size(), INF);
    queue < int > q;

    f.assign(graph.size(), 0);
    inQ[0] = true;
    dist[0] = 0;
    q.push(0);
    while(!q.empty()) {
        int cur = q.front();
        inQ[cur] = false;
        q.pop();
        for(const auto next: graph[cur]) {
            if(cap[cur][next] <= flow[cur][next]) continue;
            if(dist[next] > dist[cur] + cost[cur][next]) {
                dist[next] = dist[cur] + cost[cur][next];
                f[next] = cur;
                if(inQ[next]) continue;
                inQ[next] = true;
                q.push(next);
            }
        }
    }
    return dist[graph.size() - 1] != INF;
}

bool flowAugment(const vector < vector < int > > &graph,
                 const vector < vector < int > > &cost,
                 const vector < vector < int > > &cap,
                 vector < vector < int > > &flow,
                 int &flowCost,
                 ofstream &out) {
    int n = graph.size();
    vector < int > f;

    if(!bellmanFord(graph, cost, cap, flow, f)) return 0;

    int minFlow = INF, i;
    for(i = n - 1; i != 0; i = f[i]) {
        minFlow = min(minFlow, cap[f[i]][i] - flow[f[i]][i]);
    }
    if(!minFlow) return 0;
    for(i = n - 1; i != 0; i = f[i]) {
        flow[f[i]][i] += minFlow;
        flow[i][f[i]] -= minFlow;
        flowCost += minFlow * cost[f[i]][i];
    }
    return 1;
}

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

    int n, dim, i, j, d;

    in >> n;

    dim = 2 * n + 2;
    vector < vector < int > > graph(dim);
    vector < vector < int > > cost(dim, vector < int >(dim, 0));
    vector < vector < int > > cap(dim, vector < int >(dim , 0));
    vector < vector < int > > flow(dim, vector < int >(dim, 0));

    for(i = 1; i <= n; i++) {
        for(j = n + 1; j <= 2*n; j++) {
            in >> cost[i][j];
            cost[j][i] = -cost[i][j];
            graph[i].push_back(j);
            graph[j].push_back(i);
            cap[i][j] = 1;
        }
    }

    for(i = 1; i <= n; i++) {
        graph[0].push_back(i);
        cap[0][i] = 1;
    }
    for(i = n + 1; i <= 2 * n; i++) {
        graph[i].push_back(2*n + 1);
        graph[2*n + 1].push_back(i);
        cap[i][2*n + 1] = 1;
    }

    int cst = 0;
    while(flowAugment(graph, cost, cap, flow, cst, out));

    out << cst << '\n';
    return 0;
}