Cod sursa(job #3253644)

Utilizator MikeStrikeAgache Mihai MikeStrike Data 3 noiembrie 2024 22:38:42
Problema Flux maxim de cost minim Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.93 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <climits>
#include <cstring>

using namespace std;

const int MAXN = 1001;
const int INF = INT_MAX;

int N, M, S, D; 
int capacity[MAXN][MAXN];    
int cost[MAXN][MAXN];           
int flow[MAXN][MAXN];           
vector<int> adj[MAXN];           
int dist[MAXN];                  
int potential[MAXN];             
int parent[MAXN];               


void bellmanFord() {
    fill(dist, dist + N + 1, INF);
    dist[S] = 0;

    for (int i = 0; i < N - 1; ++i) {
        for (int u = 1; u <= N; ++u) {
            for (int v : adj[u]) {
                if (capacity[u][v] - flow[u][v] > 0 && dist[u] < INF) {
                    dist[v] = min(dist[v], dist[u] + cost[u][v]);
                }
            }
        }
    }


    for (int i = 1; i <= N; ++i) {
        potential[i] = dist[i];
    }
}


bool dijkstra() {
    fill(dist, dist + N + 1, INF);
    dist[S] = 0;
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
    pq.push({0, S});
    memset(parent, -1, sizeof(parent));

    while (!pq.empty()) {
        int d = pq.top().first;
        int u = pq.top().second;
        pq.pop();

        if (d != dist[u]) continue;

        for (int v : adj[u]) {
            if (capacity[u][v] - flow[u][v] > 0) {
                int new_cost = cost[u][v] + potential[u] - potential[v];
                if (dist[u] + new_cost < dist[v]) {
                    dist[v] = dist[u] + new_cost;
                    parent[v] = u;
                    pq.push({dist[v], v});
                }
            }
        }
    }

    // Update potentials
    for (int i = 1; i <= N; ++i) {
        if (dist[i] < INF) {
            potential[i] += dist[i];
        }
    }

    return dist[D] != INF;
}


int minCostMaxFlow() {
    int totalFlow = 0;
    int totalCost = 0;

 
    bellmanFord();

    while (dijkstra()) {
        int pathFlow = INF;

        
        for (int v = D; v != S; v = parent[v]) {
            int u = parent[v];
            pathFlow = min(pathFlow, capacity[u][v] - flow[u][v]);
        }

     
        totalFlow += pathFlow;
        totalCost += pathFlow * (dist[D] - potential[S] + potential[D]);


        for (int v = D; v != S; v = parent[v]) {
            int u = parent[v];
            flow[u][v] += pathFlow;
            flow[v][u] -= pathFlow;
        }
    }

    return totalCost;
}

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

    fin >> N >> M >> S >> D;

    memset(capacity, 0, sizeof(capacity));
    memset(cost, 0, sizeof(cost));
    memset(flow, 0, sizeof(flow));

    for (int i = 0; i < M; i++) {
        int x, y, c, z;
        fin >> x >> y >> c >> z;
        capacity[x][y] = c;
        cost[x][y] = z;
        cost[y][x] = -z;   
        adj[x].push_back(y);
        adj[y].push_back(x);
    }

    int minCost = minCostMaxFlow();
    fout << minCost << endl;

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

    return 0;
}