Cod sursa(job #3258503)

Utilizator andreea678Rusu Andreea-Cristina andreea678 Data 22 noiembrie 2024 21:54:54
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.78 kb
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
#include <fstream>
#include <algorithm>

using namespace std;

const int INF = 1e9; // O valoare mare pentru fluxul maxim
const int MAXN = 1005; // Numar maxim de noduri

int capacity[MAXN][MAXN]; // Capacitatea muchiilor
int flow[MAXN][MAXN];     // Fluxul curent pe muchii
vector<int> adj[MAXN];    // Lista de adiacenta

// Functie BFS pentru a gasi un drum augmentant
bool bfs(int source, int sink, vector<int>& parent, int n) {
    fill(parent.begin(), parent.end(), -1);
    parent[source] = -2; // Marcare speciala pentru sursa
    queue<pair<int, int>> q;
    q.push({source, INF});

    while (!q.empty()) {
        int current = q.front().first;
        int current_flow = q.front().second;
        q.pop();

        for (int next : adj[current]) {
            // Daca muchia poate fi folosita in drum si nu am vizitat-o deja
            if (parent[next] == -1 && capacity[current][next] - flow[current][next] > 0) {
                parent[next] = current;
                int new_flow = min(current_flow, capacity[current][next] - flow[current][next]);
                if (next == sink) {
                    return true;
                }
                q.push({next, new_flow});
            }
        }
    }
    return false;
}

// Funcția principala pentru calcularea fluxului maxim
int edmonds_karp(int source, int sink, int n) {
    int max_flow = 0;
    vector<int> parent(n + 1);

    while (bfs(source, sink, parent, n)) {
        int current_flow = INF;

        // Determinam fluxul minim pe drumul augmentant
        for (int node = sink; node != source; node = parent[node]) {
            int prev = parent[node];
            current_flow = min(current_flow, capacity[prev][node] - flow[prev][node]);
        }

        // Actualizam fluxurile pe drumul augmentant
        for (int node = sink; node != source; node = parent[node]) {
            int prev = parent[node];
            flow[prev][node] += current_flow;
            flow[node][prev] -= current_flow;
        }

        max_flow += current_flow;
    }

    return max_flow;
}

int main() {
    ifstream fin("maxflow.in");
    ofstream fout("maxflow.out");

    int n, m;
    fin >> n >> m;

    // Citim graful
    for (int i = 0; i < m; ++i) {
        int x, y, z;
        fin >> x >> y >> z;
        capacity[x][y] += z; // Capacitatea intre nodurile x și y
        adj[x].push_back(y);
        adj[y].push_back(x); // Adaugam si invers pentru graful rezidual
    }

    // Calculam fluxul maxim
    int source = 1; // Nodul sursa este 1
    int sink = n;   // Nodul destinate este n
    fout << edmonds_karp(source, sink, n) << endl;

    fin.close();
    fout.close();

    return 0;
}