Cod sursa(job #1337140)

Utilizator retrogradLucian Bicsi retrograd Data 8 februarie 2015 17:13:34
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.86 kb
#include <fstream>
#include <queue>
#include <vector>

using namespace std;
ifstream ka("fmcm.in");
ofstream ki("fmcm.out");

const int MAXN = 355;

int N, M, S, D;
int C[MAXN][MAXN], Cst[MAXN][MAXN];
vector<int> con[MAXN];
int raspuns;

int old_d[MAXN]; char inQ[MAXN];
queue<int> Q;

int d[MAXN], real_d[MAXN], p[MAXN];

struct varf
{
    int distanta, index;
    bool operator < (const varf arg) const
    {
        return distanta > arg.distanta;
    }
};
priority_queue <varf> H;

bool dijkstra()
{
    for(int i = 1; i <= N; i++)
        d[i] = 0x3fffffff;
    d[S] = 0;
    real_d[S] = 0;
    varf v;
    v.distanta = 0;
    v.index = S;
    H.push(v);
    while(!H.empty())
    {
        int cst = H.top().distanta, nod = H.top().index;
        H.pop();
        if (d[nod] != cst)
            continue;
        vector<int> :: iterator it;
        for (it = con[nod].begin(); it != con[nod].end(); it++)
            if (C[nod][*it])
            {
                int new_d = d[nod] + Cst[nod][*it] + old_d[nod] - old_d[*it];
                if (new_d < d[*it])
                {
                    d[*it] = new_d;
                    real_d[*it] = real_d[nod] + Cst[nod][*it];
                    p[*it] = nod;
                    varf v;
                    v.distanta = d[*it];
                    v.index = *it;
                    H.push(v);
                }
            }
    }
    for(int i = 1; i <= N; i++)
        old_d[i] = real_d[i];
    if (d[D] == 0x3fffffff)
        return false;
    int Min = 0x3fffffff, curCst = 0;
    for (int aux = D; aux != S; aux = p[aux])
    {
        Min = min(Min, C[p[aux]][aux]);
        curCst += Cst[p[aux]][aux];
    }
    raspuns += Min * real_d[D];
    for (int aux = D; aux != S; aux = p[aux])
    {
        C[p[aux]][aux] -= Min;
        C[aux][p[aux]] += Min;
    }
    return true;
}

void bellmanFord()
{
    for(int i = 1; i <= N; i++)
        old_d[i] = 0x3fffffff;
    old_d[S] = 0;
    Q.push(S);
    inQ[S] = 1;
    while(!Q.empty())
    {
        int i = Q.front();
        Q.pop();
        inQ[i] = 0;
        for (vector<int> :: iterator it = con[i].begin(); it != con[i].end(); it++)
            if (C[i][*it] && old_d[i] + Cst[i][*it] < old_d[*it])
            {
                old_d[*it] = old_d[i] + Cst[i][*it];
                if(!inQ[*it])
                {
                    inQ[*it] = 1;
                    Q.push(*it);
                }
            }
    }
}

int main()
{
    ka >> N >> M >> S >> D;
    for(int i = 1; i <= M; i++)
    {
        int x, y, c, z;
        ka >> x >> y >> c >> z;
        con[x].push_back(y);
        con[y].push_back(x);
        C[x][y] = c;
        Cst[x][y] = z;
        Cst[y][x] = -Cst[x][y];
    }
    raspuns = 0;
    bellmanFord();
    while(dijkstra());
    ki << raspuns;
}