Cod sursa(job #2025267)

Utilizator DenisONIcBanu Denis Andrei DenisONIc Data 22 septembrie 2017 11:57:45
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.96 kb
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>
#define Nmax 351
using namespace std;

int n,m,s,d,fw[Nmax][Nmax],c[Nmax][Nmax],flow,cost,viz[Nmax],mn[Nmax],sc[Nmax][Nmax],x,y,ant[Nmax],rez;
vector<int> V[Nmax];

struct bf{
    int nod,val;

    bf(int _nod,int _val) : nod(_nod), val(_val) {};
};

vector<bf> H;

bool comp(bf a,bf b)
{
    return a.val>b.val;
}

bool dijekstra()
{
    H.clear();
    H.push_back(bf(s,0));
    ant[s] = -1;

    memset(mn,0x3f,sizeof(mn));

    while (!H.empty())
    {
        bf now = H[0];
        pop_heap(H.begin(),H.end(),comp);
        H.pop_back();

        if (now.val>mn[now.nod])
            continue;

        for (int i=0;i<V[now.nod].size();i++)
        {
            int next = V[now.nod][i];

            if (fw[now.nod][next]==0)
                continue;
            if (mn[next]<=now.val+c[now.nod][next])
                continue;

            mn[next] = now.val+c[now.nod][next];
            ant[next] = now.nod;
            H.push_back(bf(next,mn[next]));
            push_heap(H.begin(),H.end(),comp);
        }
    }

    if (mn[d]>1e9)
        return false;

    int nod = d,mn2 = 1e9,c2 = 0;
    while (nod!=s)
    {
        mn2 = min(mn2,fw[ant[nod]][nod]);
        c2 += sc[ant[nod]][nod];
        nod = ant[nod];
    }
    nod = d;
    rez += c2*mn2;
    while (nod!=s)
    {
        fw[ant[nod]][nod] -= mn2;
        fw[nod][ant[nod]] += mn2;
        nod = ant[nod];
    }

    return true;
}

void Belman_ford()
{
    H.push_back(bf(s,0));
    memset(mn,0x3f,sizeof(mn));
    mn[s] = 0;

    while (!H.empty())
    {
        bf now = H[0];

        pop_heap(H.begin(),H.end(),comp);
        H.pop_back();

        if (mn[now.nod]<now.val)
            continue;

        //viz[now.nod]++;

        for (int i=0;i<V[now.nod].size();i++)
        {
            int next = V[now.nod][i];
            if (!fw[now.nod][next])
                continue;
            if (mn[next] <= now.val+c[now.nod][next])
                continue;
            else
            {
                mn[next] = now.val+c[now.nod][next];
                H.push_back(bf(next,now.val+c[now.nod][next]));
                push_heap(H.begin(),H.end(),comp);
            }
        }
    }
}

int main()
{
    freopen("fmcm.in","r",stdin);
    freopen("fmcm.out","w",stdout);
    scanf("%d%d%d%d",&n,&m,&s,&d);

    for (int i=1;i<=m;i++)
    {
        scanf("%d%d%d%d",&x,&y,&flow,&cost);
        fw[x][y] = flow;
        c[x][y] = cost;
        sc[x][y] = cost;
        fw[y][x] = 0;
        c[y][x] = -cost;
        sc[y][x] = -cost;
        V[x].push_back(y);
        if (y!=d && y!=s)
            V[y].push_back(x);
    }

    Belman_ford();

    for (int i=1;i<=n;i++)
        for (int j=1;j<=n;j++)
            c[i][j] = c[i][j]+mn[i]-mn[j];

    while (dijekstra());

    cout<<rez;
    return 0;
}