Mai intai trebuie sa te autentifici.

Cod sursa(job #597984)

Utilizator crushackPopescu Silviu crushack Data 24 iunie 2011 12:09:13
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.05 kb
#include <stdio.h>
#include <fstream>
#include <vector>
#include <queue>
#include <bitset>
#include <string.h>
#define TR(C, i)\
    for(typeof(C.begin()) i = C.begin(); i != C.end(); i++)
#define pb push_back

using namespace std;

const int nmax = 355;
const int oo = 0x3f3f;
short N, M, Source, Sink;
short Z[nmax][nmax], C[nmax][nmax], D[nmax], In[nmax], TT[nmax], F[nmax][nmax];
vector<short> G[nmax];

void InPut()
{
    ifstream in("fmcm.in");

    in >> N >> M >> Source >> Sink;

    short i, a, b, c, z;
    for(i = 1; i <= M; i++)
    {
        in >> a >> b >> c >> z;
        C[a][b] = c;
        Z[a][b] = z;
        Z[b][a] = -z;
        G[a].pb( b );
        G[b].pb( a );
    }
}

struct cmp
{
    bool operator()(const int &a, const int &b)const
    {
        return D[a] > D[b];
    }
};

priority_queue <int, vector<int>, cmp> Q;

int Dijkstra()
{
    memset(D, 0x3f, sizeof(D));
    bitset <nmax> In;

    Q.push(Source);
    D[Source] = 0;
    TT[Source] = Source;

    int nod;
    while(!Q.empty())
    {
        nod = Q.top();
        Q.pop();
        In[nod] = 0;

        TR(G[nod], it)
            if( C[nod][*it] - F[nod][*it] > 0 && D[nod] + Z[nod][*it] < D[*it])
            {
                D[*it] = D[nod] + Z[nod][*it];
                TT[*it] = nod;
                if(In[*it] == 0)
                {
                    Q.push(*it);
                    In[*it] = 1;
                }
            }
    }

    return (D[Sink] < oo);
}

void Flux()
{
    int fmin, nod, Rez = 0;
    while(Dijkstra())
    {
        fmin = oo;

        for(nod = Sink; nod != Source; nod = TT[nod])
            fmin = min(fmin, C[TT[nod]][nod] - F[TT[nod]][nod]);

        if(fmin == 0) continue;

        for(nod = Sink; nod != Source; nod = TT[nod])
            F[TT[nod]][nod] += fmin,
            F[nod][TT[nod]] -= fmin;

        Rez += (D[Sink] * fmin);
    }
    ofstream out("fmcm.out");
    out << Rez << '\n';
}

int main()
{
    InPut();
    Flux();
    return 0;
}