Cod sursa(job #2962586)

Utilizator dimi999Dimitriu Andrei dimi999 Data 8 ianuarie 2023 19:23:04
Problema Flux maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.7 kb
#include <fstream>
#include <vector>
#include <queue>
using namespace std;

fstream fin("fmcm.in");
ofstream fout("fmcm.out");

int N, M, S, D;
vector <int> v[355];
int cap[355][355], cost[355][355], flow[355][355];
int father[355];
int old[355], actual[355], dist[355];
queue <int> q;
bool inq[355];

struct Node {
    int dest, dist;

    bool operator < (const Node &other) const{
        return dist > other.dist;
    }
};

priority_queue<Node> pq;

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

    pq.push({S, 0});
    dist[S] = actual[S] = 0;

    while(!pq.empty()) {
        Node crt = pq.top();
        pq.pop();

        if(dist[crt.dest] != crt.dist)
            continue;

        for(auto it : v[crt.dest]) {
            if (flow[crt.dest][it] < cap[crt.dest][it]) {
                int d = dist[crt.dest] + cost[crt.dest][it] + old[crt.dest] - old[it];

                if (d < dist[it]) {
                    dist[it] = d, father[it] = crt.dest;
                    actual[it] = actual[crt.dest] + cost[crt.dest][it];
                    pq.push({it, dist[it]});
                }
            }
        }
    }

    for(int i = 1; i <= N; i++)
        old[i] = actual[i];

    if(dist[D] != 1e9)
        return true;
    return false;
}

void Bellman() {
    for(int i = 1; i <= N; i++) {
        old[i] = 1e9;
    }

    q.push(S);
    old[S] = 0;
    inq[S] = true;

    while(!q.empty()) {
        int node = q.front();
        q.pop();
        inq[node] = false;

        for(auto it : v[node]) {
            if (flow[node][it] < cap[node][it]) {
                if (old[it] > old[node] + cost[node][it]) {
                    if (!inq[it]) {
                        q.push(it);
                        inq[it] = true;
                    }

                    old[it] = old[node] + cost[node][it];
                }
            }
        }
    }
}

int main() {
    fin >> N >> M >> S >> D;
    for(int i = 1; i <= M; i++) {
        int x, y, c, z; fin >> x >> y >> c >> z;
        v[x].push_back(y);
        v[y].push_back(x);

        cap[x][y] = c;
        cost[x][y] = z;
        cost[y][x] = -z;
    }

    int mini = 0;
    Bellman();
    
    while(Dijkstra()) {
        int toadd = 1e9;

        for(int node = D; node != S; node = father[node]) {
            toadd = min(toadd, cap[father[node]][node] - flow[father[node]][node]);
        }

        for(int node = D; node != S; node = father[node]) {
            flow[father[node]][node] += toadd, flow[node][father[node]] -= toadd;
        }

        mini += toadd * actual[D];
    }
    fout << mini << '\n';
    return 0;
}