Cod sursa(job #1882356)

Utilizator DenisONIcBanu Denis Andrei DenisONIc Data 17 februarie 2017 09:49:37
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.52 kb
#include <fstream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>
#define Nmax 351
#define inf 1e9
using namespace std;

ofstream g("fmcm.out");

int n,m,S,D,fw[Nmax][Nmax],fwcst,C[Nmax][Nmax],d[Nmax],ant[Nmax],mn[Nmax];
vector<int> V[Nmax];
vector<pair<int,int> > H;

bool comp(pair<int,int> a,pair<int,int> b)
{
    return a.second>b.second;
}

bool dijkstra()
{
    for (int i=1;i<=n;i++)
        mn[i] = inf;
    H.push_back(make_pair(S,0));

    while (!H.empty())
    {
        int nod = H[0].first;
        int cst = H[0].second;
        pop_heap(H.begin(),H.end(),comp);
        H.pop_back();

        if (cst>mn[nod])
            continue;
        for (int i=0;i<V[nod].size();i++)
        {
            int now = V[nod][i];
            if (fw[nod][now]==0)
                continue;
            if (mn[now]>cst+d[nod]+C[nod][now] - d[now])
            {
                mn[now] = cst+d[nod]+C[nod][now] - d[now];
                ant[now] = nod;
                H.push_back(make_pair(now,mn[now]));
                push_heap(H.begin(),H.end(),comp);
            }
        }
    }
    if (mn[D]==inf)
        return false;

    int MIN = inf;
    for (int x = D;x!=S;x = ant[x])
    {
        if (MIN>fw[ant[x]][x])
            MIN = fw[ant[x]][x];
    }

    for (int x = D;x!=S;x = ant[x])
    {
        fw[ant[x]][x]-=MIN;
        fw[x][ant[x]]+=MIN;
        fwcst += C[ant[x]][x] * MIN;
    }

    return true;
}


void bellman_ford()
{
    vector<pair <int,int> > c;

    for (int i=1;i<=n;i++)
        d[i] = inf;

    d[S] = 0;
    c.push_back(make_pair(S,0));
    for (int i=0; i<c.size();i++)
    {
        int nod = c[i].first,cst = c[i].second;
        if (cst>d[nod])
            continue;
        for (int j=0;j<V[nod].size();j++)
        {
            int now = V[nod][j];
            if (fw[nod][now])
            {
                if (cst + C[nod][now]<d[now])
                {
                    d[now] = cst + C[nod][now];
                    c.push_back(make_pair(now,d[now]));
                }
            }
        }
    }

}

int main()
{
    freopen("fmcm.in","r",stdin);
    scanf("%d%d%d%d",&n,&m,&S,&D);
    for (int i=1;i<=m;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        scanf("%d%d",&fw[x][y],&C[x][y]);

        V[x].push_back(y);
        V[y].push_back(x);
        C[y][x] = -C[x][y];
    }

    bellman_ford();

    while (dijkstra());

    g<<fwcst;

    return 0;
}