Cod sursa(job #2725679)

Utilizator Marius7122FMI Ciltea Marian Marius7122 Data 19 martie 2021 15:13:14
Problema Flux maxim de cost minim Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.11 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <queue>

using namespace std;

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

const int N = 355;
const int INF = 1e9;

int n, m, source, sink, fmax, costMin;
int t[N], cap[N][N], cost[N][N], flow[N][N];
vector<int> dist;
vector<int> g[N];

vector<bool> inCoada;
void BellmanFordCoada(int startNode)
{
    inCoada.assign(n + 1, false);
    dist.assign(n + 1, INF);

    queue<int> coada;
    coada.push(startNode);
    inCoada[startNode] = true;
    dist[startNode] = 0;
    t[startNode] = 0;

    while(!coada.empty())
    {
        int x = coada.front();
        coada.pop();
        inCoada[x] = false;

        for (int y : g[x])
        {
            if (dist[x] + cost[x][y] < dist[y] && flow[x][y] != cap[x][y])
            {
                t[y] = x;
                dist[y] = dist[x] + cost[x][y];
                if (!inCoada[y])
                {
                    coada.push(y);
                    inCoada[y] = true;
                }
            }
        }
    }
}

void maxFlowMinCost()
{
    do
    {
        BellmanFordCoada(source);

        if(dist[sink] == INF)
            break;

        int fmin = 1 << 30;
        for(int node = sink; node != source; node = t[node])
            fmin = min(fmin, cap[t[node]][node] - flow[t[node]][node]);

        fmax += fmin;
        for(int node = sink; node != source; node = t[node])
        {
            flow[t[node]][node] += fmin;
            flow[node][t[node]] -= fmin;
        }

        costMin += dist[sink] * fmin;
    } while(dist[sink] != INF);
}

void addEdge(int x, int y, int c, int z)
{
    g[x].push_back(y);
    g[y].push_back(x);
    cap[x][y] = c;
    cap[y][x] = 0;
    cost[x][y] = z;
    cost[y][x] = -z;
}

int main()
{
    fin >> n >> m >> source >> sink;

    for (int i = 0; i < m; i++)
    {
        int x, y, c, z;
        fin >> x >> y >> c >> z;
        addEdge(x, y, c, z);
    }

    maxFlowMinCost();
    fout << costMin;

    return 0;
}


/*





*/