Cod sursa(job #1844404)

Utilizator alexandru822Bosinta Alexandru alexandru822 Data 9 ianuarie 2017 23:04:42
Problema Flux maxim de cost minim Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 3.08 kb
#include <fstream>
#include <vector>
#include <queue>
#include <string.h>
using namespace std;
ofstream out("fmcm.out");
ifstream in("fmcm.in");

const int N_MAX = 350;

vector<int> vecini[1 + N_MAX];
int capacity[1 + N_MAX][1 + N_MAX];
int cost[1 + N_MAX][1 + N_MAX];

int N, M, S, D;
bool inQ[1 + N_MAX];
int old_d[1 + N_MAX], d[1 + N_MAX], new_d[1+N_MAX];
int tata[1 + N_MAX];
bool inPQ[1 + N_MAX];
int min(int a, int b)
{
    return (a<b)?a:b;
}

struct cmp
{
    bool operator() (const pair<int, int> &x, const pair<int, int> &y)
    {
        return (x.first > y.first);
    }
};

int Djikstra()
{
    priority_queue<pair<int, int>, vector<pair<int,int>>, cmp> frontiera;
    frontiera.push(make_pair(0,S));
    memset(inPQ, 0, sizeof(inPQ));
    memset(d, 0x3f, sizeof(d));
    d[S] = 0;
    while(!frontiera.empty())
    {
        int nod = frontiera.top().second;
        int cst = frontiera.top().first;
        frontiera.pop();
        if(nod == D || d[nod] != cst) continue;
        for(int m : vecini[nod])
        {
            int newcost = d[nod] + old_d[nod] - old_d[m] + cost[nod][m];
            if(capacity[nod][m] && newcost < d[m])
            {
                d[m] = newcost;
                tata[m] = nod;
                new_d[m] = new_d[nod] + cost[nod][m];
                if(inPQ[m]) continue;
                inPQ[m] = true;
                frontiera.push(make_pair(d[m],m));
            }
        }
        inPQ[nod] = false;
    }
    memcpy(old_d, new_d, sizeof(d));
    if(d[D] == 0x3f3f3f3f)
        return false;
    return true;
}

void Bellman_Ford()
{
    queue<int> frontiera;
    frontiera.push(S);
    inQ[S] = 1;
    memset(old_d, 0x3f, sizeof(old_d));
    old_d[S] = 0;
    while(!frontiera.empty())
    {
        int nod = frontiera.front();
        frontiera.pop();
        if(nod == D) continue;
        for(int m : vecini[nod])
        {
            if(capacity[nod][m] && (old_d[nod] + cost[nod][m] < old_d[m]))
            {
                old_d[m] = old_d[nod] + cost[nod][m];
                if(inQ[m]) continue;
                inQ[m] = true;
                frontiera.push(m);
            }
        }
        inQ[nod] = 0;
    }


}

int main()
{
    in >> N >> M >> S >> D;
    for(int i = 0; i < M; i++)
    {
        int x, y, c, z;
        in >> x >> y >> c >> z;
        vecini[x].push_back(y);
        vecini[y].push_back(x);
        capacity[x][y] = c;
        cost[x][y] = z;
        cost[y][x] = -z;
    }

    Bellman_Ford();
    int total = 0;
    while(Djikstra())
    {
        int nod = D;
        int fmin = 0x3f3f3f3f;
        for(; nod!=S; nod = tata[nod])
            fmin = min(fmin, capacity[tata[nod]][nod]);
        if(fmin == 0) continue;
        nod = D;
        int sum = 0;
        for(; nod != S; nod = tata[nod])
        {
            capacity[tata[nod]][nod] -= fmin;
            capacity[nod][tata[nod]] += fmin;

            sum += fmin * cost[tata[nod]][nod];
        }
        total += sum;
    }
    out << total;
    return 0;
}