Cod sursa(job #2462471)

Utilizator alex_HarryBabalau Alexandru alex_Harry Data 27 septembrie 2019 13:26:38
Problema Flux maxim de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.92 kb
#include <fstream>
#include <queue>
#include <cstring>
#include <set>
using namespace std;
ifstream f("fmcm.in");
ofstream g("fmcm.out");
int N, M;
vector <int> G[355];
int Cost[355][355];
int C[355][355], F[355][355];
int Source, Dest;
bool InQ[355];
int Dist[355], D[355], realD[355];
priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > S;
queue <int> Q;
int TT[355], MaxFlow, MinC;
void Read()
{
    f >> N >> M >> Source >> Dest;
    for(int i = 1; i <= M; i++)
    {
        int x, y, c, z;
        f >> x >> y >> c >> z;
        G[x].push_back(y);
        G[y].push_back(x);
        Cost[x][y] = z;
        Cost[y][x] = -z;
        C[x][y] += c;
    }
}

void bellmanFord(int node)
{
    for(int i = 1; i <= N; i++)
        Dist[i] = 0x3f3f3f3f;
    Q.push(node);
    InQ[node] = 1;
    Dist[node] = 0;
    while(!Q.empty())
    {
        int node = Q.front();
        InQ[node] = 0;
        Q.pop();
        for(int i = 0; i < G[node].size(); i++)
        {
            int neighb = G[node][i];
            if(C[node][neighb] == 0)
                continue;
            if(Dist[neighb] > Dist[node] + Cost[node][neighb])
            {
                Dist[neighb] = Dist[node] + Cost[node][neighb];
                if(InQ[neighb] == 0)
                {
                    InQ[neighb] = 1;
                    Q.push(neighb);
                }
            }
        }
    }
}

bool dijsktra()
{
     for(int i = 1; i <= N; i++)
        D[i] = 0x3f3f3f3f, TT[i] = -1;
    D[Source] = realD[Source] = 0;
    S.push(make_pair(0, Source));
    while(!S.empty())
    {
        pair <int, int> p = S.top();
        int d = p.first, node = p.second;
        S.pop();
        if(D[node] < d)
            continue;
        for(int i = 0; i < G[node].size(); i++)
        {
            int neighb = G[node][i];
            if(C[node][neighb] - F[node][neighb] > 0)
            {
                int e = Cost[node][neighb] + Dist[node] - Dist[neighb];
                if(d + e < D[neighb])
                {
                    D[neighb] = d + e;
                    S.push(make_pair(D[neighb], neighb));
                    realD[neighb] = realD[node] + Cost[node][neighb];
                    TT[neighb] = node;
                }
            }
        }
    }
    return TT[Dest] != -1;
}

void Solve()
{
    while(dijsktra())
    {
        int Min = 0x3f3f3f3f;
        for(int i = Dest; i != Source; i = TT[i])
        {
            Min = min(Min, C[TT[i]][i] - F[TT[i]][i]);
        }
        MaxFlow += Min;
        MinC += Min * realD[Dest];
        for(int i = Dest; i != Source; i = TT[i])
        {
            F[TT[i]][i] += Min;
            F[i][TT[i]] -= Min;
        }
        memcpy(Dist, realD, sizeof(Dist));
    }
    g << MinC << "\n";
}
int main()
{
    Read();
    bellmanFord(Source);
    Solve();
    return 0;
}