Cod sursa(job #2717306)

Utilizator trifangrobertRobert Trifan trifangrobert Data 7 martie 2021 01:27:41
Problema Flux maxim de cost minim Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.98 kb
#include <bits/stdc++.h>

using namespace std;

const int NMAX = 350;
const int INF = (1 << 30);
int N, M, source, sink;
vector <int> graph[NMAX + 5];
int cap[NMAX + 5][NMAX + 5], cost[NMAX + 5][NMAX + 5];
int oldDist[NMAX + 5];
int dist[NMAX + 5];
int realDist[NMAX + 5];
int father[NMAX + 5];
bool inq[NMAX + 5];

void BellmanFord(){
    for (int i = 1;i <= N;++i)
        oldDist[i] = INF;
    oldDist[source] = 0;
    queue <int> q;
    q.push(source);
    inq[source] = true;
    while (!q.empty()){
        int node = q.front();
        inq[node] = false;
        q.pop();
        for (auto& x : graph[node]){
            if (cap[node][x] > 0){
                if (oldDist[x] > oldDist[node] + cost[node][x]){
                    oldDist[x] = oldDist[node] + cost[node][x];
                    if (inq[x] == false){ ///spfa <3
                        inq[x] = true;
                        q.push(x);
                    }
                }
            }
        }
    }
}

priority_queue <pair <int, int>> pq;

bool Dijkstra(){
    for (int i = 1;i <= N;++i)
        dist[i] = realDist[i] = INF;
    dist[source] = realDist[source] = 0;
    pq.push(make_pair(0, source));
    while (!pq.empty()){
        int node = pq.top().second;
        int c = pq.top().first;
        pq.pop();
        if (dist[node] == c){
            for (auto& x : graph[node]){
                if (cap[node][x] > 0){
                    int newDist = dist[node] + oldDist[node] - oldDist[x] + cost[node][x];
                    if (newDist < dist[x]){
                        dist[x] = newDist;
                        realDist[x] = realDist[node] + cost[node][x];
                        father[x] = node;
                        pq.push(make_pair(-dist[x], x));
                    }
                }
            }
        }
    }
    for (int i = 1;i <= N;++i)
        oldDist[i] = realDist[i];
    return (dist[sink] != INF);
}

int main(){
    ifstream fin("fmcm.in");
    ofstream fout("fmcm.out");
    fin >> N >> M >> source >> sink;
    for (int i = 1;i <= M;++i){
        int x, y, c, z;
        fin >> x >> y >> c >> z;
        graph[x].push_back(y);
        graph[y].push_back(x);
        cap[x][y] = c;
        cost[x][y] = z;
        cost[y][x] = -cost[x][y];
    }
    int maxFlow = 0, minCost = 0;
    BellmanFord();
    while (Dijkstra()){ ///edmond karp buuu
        int deltaFlow = INF;
        int deltaCost = 0;
        for (int node = sink;node != source;node = father[node]){
            deltaFlow = min(deltaFlow, cap[father[node]][node]);
            deltaCost += cost[father[node]][node];
        }
        maxFlow += deltaFlow;
        minCost += deltaFlow * deltaCost;
        for (int node = sink;node != source;node = father[node]){
            cap[father[node]][node] -= deltaFlow;
            cap[node][father[node]] += deltaFlow;
        }
    }
    fout << minCost << "\n";
    fin.close();
    fout.close();
    return 0;
}