Cod sursa(job #3191351)

Utilizator GFA03Gavrila Florin-Alexandru GFA03 Data 9 ianuarie 2024 14:50:34
Problema Cc Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.69 kb
#include <vector>
#include <iostream>
#include <fstream>
#include <climits>
#include <queue>
#include <unordered_map>

using namespace std;

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

vector<vector<int>> adj, dist;
vector<unordered_map<int, int>> capacity, flow;
int source, target, n;
vector<int> parent, minDist;
const int INF = INT_MAX;

int result = 0;

int bfs()
{
    for (int i = 0; i <= target; i++)
    {
        parent[i] = -1;
        minDist[i] = INF;
    }

    minDist[source] = 0;
    queue<pair<int, int>> q;
    q.push({source, INF});

    while (!q.empty())
    {
        int currentNode = q.front().first;
        int currentFlow = q.front().second;
        q.pop();

        for (auto &neigh : adj[currentNode])
        {
            if (minDist[neigh] > minDist[currentNode] + dist[currentNode][neigh] && capacity[currentNode][neigh] > flow[currentNode][neigh])
            {
                parent[neigh] = currentNode;
                int residualFlow = capacity[currentNode][neigh] - flow[currentNode][neigh];
                int bottleneck = min(currentFlow, residualFlow);

                minDist[neigh] = minDist[currentNode] + dist[currentNode][neigh];

                q.push({neigh, bottleneck});
            }
        }
    }
    return parent[target] >= 0;
}

void maxflow()
{
    int newFlow;
    parent.resize(target + 2);
    while (true)
    {
        newFlow = bfs();
        if (newFlow == 0)
            break;

        int currentNode = target;
        while (currentNode != source)
        {
            int parentNode = parent[currentNode];
            flow[parentNode][currentNode] += newFlow;
            flow[currentNode][parentNode] -= newFlow;
            currentNode = parentNode;
        }
        result += minDist[target];
    }
}

void read()
{
    fin >> n;
    source = 0;
    target = 2 * n + 1;
    capacity.resize(target + 1);
    flow.resize(target + 1);
    adj.resize(target + 1);
    dist.resize(target + 1, vector<int>(target + 1));
    minDist.resize(target + 1);
    int x, y;
    for (int i = 1; i <= n; i++)
    {
        adj[source].push_back(i);
        adj[i].push_back(source);
        capacity[source][i] = 1;

        for (int j = 1; j <= n; ++j)
        {
            fin >> y;
            adj[i].push_back(j + n);
            adj[j + n].push_back(i);
            capacity[i][j + n] = 1;
            dist[i][j + n] = y;
            dist[j + n][i] = -y;
        }

        adj[i + n].push_back(target);
        adj[target].push_back(i + n);
        capacity[i + n][target] = 1;
    }
}

int main()
{
    read();
    maxflow();

    fout << result;
    return 0;
}