Cod sursa(job #2986748)

Utilizator MihaiZ777MihaiZ MihaiZ777 Data 1 martie 2023 00:26:56
Problema Cc Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.88 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;

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

const int INF = 0x3f3f3f3f;
const int MAX_N = 205;

struct Edge {
    int destination;
    int cost;

    bool operator < (const Edge& other) const {
        return cost > other.cost;
    }
};

int n;
int graph[MAX_N][MAX_N];
int flow[MAX_N][MAX_N];
int father[MAX_N];
int distances[MAX_N];
vector <Edge> dijkstraGraph[MAX_N];
priority_queue <Edge> heap;
int ans = 0;


void InitHeap() {
    while (!heap.empty()) {
        heap.pop();
    }
    heap.push({0, 0});
}

bool Dijkstra() {
    InitHeap();
    memset(father, 0, sizeof(father));
    memset(distances, INF, sizeof(distances));

    distances[0] = 0;
    father[0] = 0;

    while (!heap.empty()) {
        Edge edge = heap.top();
        heap.pop();
        int node = edge.destination;

        for (Edge newEdge : dijkstraGraph[node]) {
            int newNode = newEdge.destination;
            if (distances[newNode] <= distances[node] + newEdge.cost) {
                continue;
            }

            if (graph[node][newNode] - flow[node][newNode] > 0) {
                distances[newNode] = distances[node] + newEdge.cost;
                newEdge.cost = distances[newNode];
                heap.push(newEdge);
                father[newNode] = node;
            }
        }
    }

    if (father[2 * n + 1]) {
        return true;
    }

    return false;
}

int GetMin() {
    int node = 2 * n + 1;
    int minVal = INF;

    while (father[node] != node) {
        int parent = father[node];
        minVal = min(minVal, graph[parent][node] - flow[parent][node]);
        node = parent;
    }
    return minVal;
}

void UpdateFlow(int value) {
    int node = 2 * n + 1;
    while (father[node] != node) {
        int parent = father[node];
        flow[parent][node] += value;
        flow[node][parent] -= value;
        node = parent;
    }
}

int main() {
    fin >> n;
    for (int i = 1; i <= n; i++) {
        for (int j = n + 1; j <= n * 2; j++) {
            int distance;
            fin >> distance;
            graph[i][j] = 1;

            dijkstraGraph[i].push_back({j, distance});
            dijkstraGraph[j].push_back({i, -distance});
        }
    }

    for (int i = 1; i <= n; i++) {
        dijkstraGraph[0].push_back({i, 0});
        dijkstraGraph[i].push_back({0, 0});

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

        graph[n + i][n * 2 + 1] = 1; 
    }

    while (Dijkstra()) {
        int minVal = GetMin();
        ans += minVal * distances[2 * n + 1];
        UpdateFlow(minVal);
    }

    fout << ans << '\n';
}