Cod sursa(job #3190096)

Utilizator AndreeaHzmAndreea Huzum AndreeaHzm Data 6 ianuarie 2024 23:22:04
Problema Cc Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.84 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

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

vector<int> x[1001];
pair<int, int> h[1001][1001];
int n, nr, sol, p[1001];
int dist[1001], prec[1001], init[1001][1001];

void update(int a, int v) {
    while (prec[a] != -1) {
        h[prec[a]][a].first -= v;
        sol += v * init[prec[a]][a];
        h[a][prec[a]].first += v;
        sol -= v * init[a][prec[a]];
        a = prec[a];
    }
}

void initializeGraph() {
    for (int i = 1; i <= n; i++) {
        x[0].push_back(i);
        x[i].push_back(0);
        h[0][i] = {1, 0};
        h[i][0] = {0, 0};
        init[0][i] = 0;
    }

    for (int i = 1; i <= n; i++) {
        x[i + n].push_back(nr);
        x[nr].push_back(i + n);
        h[i + n][nr] = {1, 0};
        h[nr][i + n] = {0, 0};
        init[i + n][nr] = 0;
    }

    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++) {
            fin >> h[i][j + n].second;
            x[i].push_back(j + n);
            x[j + n].push_back(i);
            h[i][j + n].first = 1;
            h[j + n][i] = {0, -h[i][j + n].second};
            init[i][j + n] = h[i][j + n].second;
        }
}

void bfs(queue<int>& q) {
    while (!q.empty()) {
        int a = q.front();
        q.pop();
        for (int i : x[a])
            if (h[a][i].first > 0 && dist[i] > dist[a] + h[a][i].second) {
                prec[i] = a;
                dist[i] = dist[a] + h[a][i].second;
                q.push(i);
            }
    }
}

void findMaxFlow() {
    queue<int> q;
    vector<int>::iterator I;

    q.push(0);
    while (!q.empty()) {
        int a = q.front();
        q.pop();
        p[a] = 0;

        for (I = x[a].begin(); I != x[a].end(); I++)
            if (h[a][*I].first > 0 && dist[*I] > dist[a] + h[a][*I].second) {
                prec[*I] = a;
                dist[*I] = dist[a] + h[a][*I].second;
                if (p[*I] == 0) p[*I] = 1, q.push(*I);
            }
    }

    if (dist[nr] != 1e9) {
        while (dist[nr] != 1e9) {
            update(nr, 1);

            for (int i = 0; i <= nr; i++)
                for (I = x[i].begin(); I != x[i].end(); I++)
                    h[i][*I].second += dist[i] - dist[*I];

            fill(begin(dist), end(dist), 1e9);
            fill(begin(p), end(p), 0);
            dist[0] = 0;
            prec[0] = -1;
            q.push(0);
            bfs(q);
        }
    }
}

int main() {
    fin >> n;
    nr = n + n + 1;

    initializeGraph();

    fill(begin(dist), end(dist), 1e9);
    fill(begin(p), end(p), 0);
    prec[0] = -1;
    p[0] = 1;
    dist[0] = 0;

    queue<int> q;
    q.push(0);

    bfs(q);
    if (dist[nr] != 1e9)
        findMaxFlow();

    fout << sol;
    return 0;
}