Cod sursa(job #2380783)

Utilizator victorv88Veltan Victor victorv88 Data 15 martie 2019 15:06:21
Problema Flux maxim de cost minim Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.42 kb
#include <iostream>

#include <fstream>

#include <vector>

#include <bitset>

#include <queue>

#include <set>

#define MAX 0x3f3f3f3f

using namespace std;



ifstream f("fmcm.in");

ofstream g("fmcm.out");



int start_point, end_point, n, m, rezidual[355][355], cost_muchie[355][355], a, b, c, d;

int distante_calculate[355], distante_reale[355], father[355], dp[355];

int cost_minim;



set<pair<int,int> >prioritate;

queue<int>q;

bitset<355>in_queue;

vector<int>graph[355];



void bellman()

{

    in_queue[start_point]=1;

    for (int i=1; i<=n; ++i)

        distante_calculate[i]=MAX;

    q.push(start_point);

    distante_calculate[start_point]=0;

    while (!q.empty())

    {

        int nod=q.front();

        q.pop();

        in_queue[nod]=0;

        for (auto &v:graph[nod])

        {

            if (rezidual[nod][v])

            {

                if (distante_calculate[v]>distante_calculate[nod]+cost_muchie[nod][v])

                {

                    distante_calculate[v]=distante_calculate[nod]+cost_muchie[nod][v];

                    if (!in_queue[v])

                    {

                        q.push(v);

                        in_queue[v]=1;

                    }

                }

            }

        }

    }

}



bool dijkstra()

{

    for (int i=1; i<=n; ++i)

        dp[i]=distante_reale[i]=MAX;

    dp[start_point]=distante_reale[start_point]=0;

    prioritate.insert({0,start_point});

    while (!prioritate.empty())

    {

        auto sus=prioritate.begin();

        int nod=sus->second;

        int valoare= -(sus->first);

        prioritate.erase(prioritate.begin());

        if (valoare!=dp[nod])

            continue;

        for (auto &v:graph[nod])

        {

            if (rezidual[nod][v])

            {

                if (dp[v]>dp[nod]+cost_muchie[nod][v]+distante_calculate[nod]-distante_calculate[v])

                {
                    if (dp[v]!=MAX)
                    prioritate.erase({-dp[v],v});
                    dp[v]=dp[nod]+cost_muchie[nod][v]+distante_calculate[nod]-distante_calculate[v];

                    distante_reale[v]=distante_reale[nod]+cost_muchie[nod][v];

                    father[v]=nod;

                    prioritate.insert({-dp[v],v});

                }

            }

        }

    }

    for (int i=1; i<=n; ++i)

        distante_calculate[i]=distante_reale[i];

    if (distante_calculate[end_point]==MAX)

        return 0;

    int mini=MAX;

    for (int nod=end_point; nod!=start_point; nod=father[nod])

    {

        if (rezidual[father[nod]][nod]<mini)

            mini=rezidual[father[nod]][nod];

    }

    for (int nod=end_point; nod!=start_point; nod=father[nod])

    {

        rezidual[father[nod]][nod]-=mini;

        rezidual[nod][father[nod]]+=mini;

    }

    cost_minim+=(mini*distante_calculate[end_point]);

    return 1;

}



int main()

{

    f >> n >> m >> start_point >> end_point;

    for (int i=1; i<=m; ++i)

    {

        f >> a >> b >> c >> d;

        graph[a].push_back(b);

        graph[b].push_back(a);

        rezidual[a][b]=c;

        cost_muchie[a][b]=d;

        cost_muchie[b][a]=-d;

    }

    bellman();

    while (dijkstra());

    g << cost_minim;

    return 0;

}