Cod sursa(job #2557866)

Utilizator KappaClausUrsu Ianis Vlad KappaClaus Data 26 februarie 2020 09:10:18
Problema Flux maxim de cost minim Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.18 kb
#include <bits/stdc++.h>

using namespace std;

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

const int N_MAX = 350 + 1;
const int oo = 1 << 29;

vector<vector<int>> graph(N_MAX, vector<int>());

int C[N_MAX][N_MAX], F[N_MAX][N_MAX], COST[N_MAX][N_MAX], N, M, S, D;

vector<int> dist(N_MAX, oo);
vector<bool> inPQ(N_MAX, false);
vector<int> cntInPQ(N_MAX, 0);
vector<int> parent(N_MAX, 0);

struct Compare
{
    bool operator ()(int node_x, int node_y)
    {
        return dist[node_x] > dist[node_y];
    }
};

priority_queue<int, vector<int>, Compare> PQ;

bool Dijkstra()
{
    fill(dist.begin(), dist.end(), oo);
    fill(cntInPQ.begin(), cntInPQ.end(), 0);

    dist[S] = 0;
    cntInPQ[S] = 1;
    inPQ[S] = true;
    PQ.push(S);


    while(PQ.empty() == false)
    {
        int node = PQ.top();
        PQ.pop();
        inPQ[node] = false;

        for(auto& next : graph[node])
        {
            if(C[node][next] == F[node][next]) continue;

            if(dist[node] + COST[node][next] < dist[next])
            {
                dist[next] = dist[node] + COST[node][next];

                parent[next] = node;

                if(inPQ[next] == false)
                {
                    inPQ[next] = true;
                    PQ.push(next);
                    cntInPQ[next]++;

                    if(cntInPQ[next] == N) return false;
                }
            }
        }
    }

    return (dist[D] != oo);
}


int main()
{
    fin >> N >> M >> S >> D;

    for(int i = 1; i <= M; ++i)
    {
        int x, y, c, z;

        fin >> x >> y >> c >> z;

        C[x][y] = c;

        COST[x][y] = z;
        COST[y][x] = -z;

        graph[x].push_back(y);
    }


    int mincost = 0;

    while(Dijkstra())
    {
        int minFlow = oo;

        for(int i = D; i != S; i = parent[i])
            minFlow = min(minFlow, C[parent[i]][i] - F[parent[i]][i]);

        for(int i = D; i != S; i = parent[i])
        {
            F[parent[i]][i] += minFlow;
            F[i][parent[i]] -= minFlow;

            mincost += (minFlow * COST[parent[i]][i]);
        }
    }

    fout << mincost;
}