Cod sursa(job #3194146)

Utilizator AlexCRCAlexandru-Emilian Craciun AlexCRC Data 17 ianuarie 2024 09:39:30
Problema Cc Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.86 kb
#include <fstream>
#include <cstring>
using namespace std;

int n, fl[256][256], cost[256][256], dist[256], pred[256];

ifstream f("cc.in");
ofstream g("cc.out");

// Find augmenting paths using the Bellman-Ford
// Check if there is flow between node i and node j. If the value is greater than zero, there is a flow on that edge.
// Check if updating the distance for node j through node i would reduce the distance.
//    Distance is determined by edge capacity and distance to the source node.
//    If condition is met, consider it as a path for growth.

int bellman()
{
    memset(pred, -1, sizeof(pred));
    memset(dist, 0x3f3f, sizeof(dist));
    dist[0] = 0;
    pred[0] = 0;

    // Path of growth is found
    bool ok = true;

    // Until no more path of growth are found
    while (ok == true)
    {
        ok = false;
        for (int i = 0; i <= 2 * n + 1; ++i)
            for (int j = 0; j <= 2 * n + 1; ++j)

                // Check if there is flow on the edge from node i to node j,
                // and if updating the distance for node j through node i would reduce the distance
                if (fl[i][j] > 0 && dist[j] > dist[i] + cost[i][j])
                {
                    // Update the distance and predecessor
                    dist[j] = dist[i] + cost[i][j];
                    pred[j] = i;

                    // Path of growth is found
                    ok = true; 
                }
    }

    // If there are no path to the sink, return 0, otherwise return 0.
    if (pred[2 * n + 1] == -1)
        return 0;
    return 1;
}

// Function to find the minimum cost maximum flow
void flux()
{
    // Initialize flows from source to the first set of nodes 
    // And from the second set of nodes to the sink
    for (int i = 1; i <= n; ++i)
    {
        fl[0][i] = 1;
        fl[n + i][2 * n + 1] = 1;
    }

    // Continue finding augmenting paths and finding flow
    while (bellman() == 1)
    {
        int p = 2 * n + 1;

        // Update the flow along the augmenting path
        while (p)
        {
            fl[pred[p]][p]--;
            fl[p][pred[p]]++;
            p = pred[p];
        }
    }

    // Calculate and output the minimum cost
    int sum = 0;
    for (int i = 1; i <= n; ++i)
    {
        for (int j = n + 1; j <= 2 * n; ++j)
        {
            // If there is no flow between node i and node j, add the cost to the sum
            if (fl[i][j] == 0)
            {
                sum += cost[i][j];
            }
        }
    }
    g << sum << '\n';
    g.close();
}

int main()
{
    f >> n;
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= n; ++j)
        {
            f >> cost[i][j + n];
            cost[j + n][i] = -cost[i][j + n];
            fl[i][j + n] = 1;
        }

    f.close();
    flux();

    return 0;
}