Cod sursa(job #3188656)

Utilizator willOcanaru Mihai will Data 3 ianuarie 2024 17:03:14
Problema Cc Scor 50
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.23 kb
#include <stdio.h>
#include <string.h>
#include <queue>
#include <vector>
#include <algorithm>
#include <climits>

#define MAX_NODES 125
#define LARGE_NUMBER INT_MAX

using namespace std;

const char INPUT_FILE[] = "cc.in";
const char OUTPUT_FILE[] = "cc.out";

int cost[MAX_NODES][MAX_NODES];
int capacity[MAX_NODES][MAX_NODES];
int flow[MAX_NODES][MAX_NODES];
int potential[MAX_NODES];
int parent[MAX_NODES];

bool bellmanFord(int numNodes) {
    int currentNode, nextNode;
    vector<bool> visited(MAX_NODES, false);
    queue<int> bfsQueue;

    bfsQueue.push(0);

    // Initialize potential and visited arrays
    for(int i = 1; i <= 2 * numNodes + 1; ++i)
        potential[i] = LARGE_NUMBER;
    potential[0] = 0;
    visited[0] = true;

    // Perform BFS to find the shortest path in terms of potential
    while (!bfsQueue.empty()) {
        currentNode = bfsQueue.front();
        bfsQueue.pop();

        // Explore neighbors of the current node
        for (nextNode = 0; nextNode <= 2 * numNodes + 1; ++nextNode) {
            if (capacity[currentNode][nextNode] > flow[currentNode][nextNode] &&
                cost[currentNode][nextNode] + potential[currentNode] < potential[nextNode]) {
                potential[nextNode] = cost[currentNode][nextNode] + potential[currentNode];
                parent[nextNode] = currentNode;

                if (!visited[nextNode]) {
                    visited[nextNode] = true;
                    bfsQueue.push(nextNode);
                }
            }
        }

        visited[currentNode] = false;
    }

    // Return true if there is an augmenting path
    return potential[2 * numNodes + 1] != LARGE_NUMBER;
}

int calculateMaxFlow(int numNodes) {
    int totalCost = 0, currentNode, minFlow;

    while (bellmanFord(numNodes)) {
        minFlow = LARGE_NUMBER;

        // Find the minimum flow in the augmenting path
        for (currentNode = 2 * numNodes + 1; currentNode; currentNode = parent[currentNode]) {
            minFlow = min(minFlow, capacity[parent[currentNode]][currentNode] - flow[parent[currentNode]][currentNode]);
        }

        // Update the flow along the augmenting path
        for (currentNode = 2 * numNodes + 1; currentNode; currentNode = parent[currentNode]) {
            flow[parent[currentNode]][currentNode] += minFlow;
            flow[currentNode][parent[currentNode]] -= minFlow;
        }

        // Update the total cost
        totalCost += potential[2 * numNodes + 1] * minFlow;
    }

    return totalCost;
}

int main() {
    int i, j, numNodes;  // Declare numNodes here
    freopen(INPUT_FILE, "r", stdin);
    scanf("%d", &numNodes);

    // Fill in the cost matrix based on the input
    for (i = 1; i <= numNodes; ++i) {
        for (j = 1; j <= numNodes; ++j) {
            scanf("%d", &cost[i][numNodes + j]);
            cost[numNodes + j][i] = -cost[i][numNodes + j];
            capacity[i][numNodes + j] = 1;
        }
    }
    fclose(stdin);

    // Set the capacities for source and sink nodes
    for (i = 1; i <= numNodes; ++i) 
        capacity[0][i] = 1;

    for (i = numNodes + 1; i <= 2 * numNodes; ++i) 
        capacity[i][2 * numNodes + 1] = 1;

    freopen(OUTPUT_FILE, "w", stdout);
    printf("%d\n", calculateMaxFlow(numNodes));
    fclose(stdout);

    return 0;
}