Cod sursa(job #304746)

Utilizator Mishu91Andrei Misarca Mishu91 Data 15 aprilie 2009 10:52:38
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.98 kb
#include <cstdio>
#include <vector>
#include <queue>
#include <bitset>

using namespace std;

#define MAX_N 355
#define INF 0x3f3f3f3f

#define foreach(V) for(typeof (V).begin() it = (V).begin(); it != (V).end(); ++it)

vector <short int> G[MAX_N];
short int C[MAX_N][MAX_N], F[MAX_N][MAX_N], Cost[MAX_N][MAX_N];
int Dist[MAX_N], T[MAX_N], P[MAX_N];
short int N, M, S, D;
int g[MAX_N];

void citire()
{
    scanf("%hd %hd %hd %hd",&N, &M, &S, &D);

    while(M--)
    {
        short int a, b, c, cost;
        scanf("%hd %hd %hd %hd",&a, &b, &c, &cost);

        G[a].push_back(b);
        G[b].push_back(a);
        C[a][b] = c;
        Cost[a][b] = cost;
        Cost[b][a] = -cost;
    }
    for(int i = 1; i <= N; ++i)
        g[i] = G[i].size();
}

int Belman()
{
    for(int i = 1; i <= N; ++i)
        Dist[i] = INF;
    bitset <MAX_N> viz;
    queue <int> Q;

    Q.push(S);
    Dist[S] = 0;
    viz[S] = 1;

    for(;!Q.empty(); Q.pop())
    {
        int nod = Q.front();
        viz[nod] = 0;

        for(int i = 0; i < g[nod]; ++i)
        {
            int act = G[nod][i];
            if(C[nod][act] > F[nod][act] && Dist[nod] + Cost[nod][act] < Dist[act])
            {
                Dist[act] = Dist[nod] + Cost[nod][act];
                T[act] = nod;

                if(!viz[act])
                {
                    Q.push(act);
                    viz[act] = 1;
                }
            }
        }
    }
    return (Dist[D] < INF);
    
}

void flux()
{
    int fmin, flow = 0;
    while(Belman())
    {
        int m = 0;
        for(int i = D; i; i = T[i])
            P[++m] = i;

        fmin = INF;

        for(int i = 1; i < m; ++i)
            fmin = min(fmin, C[P[i+1]][P[i]] - F[P[i+1]][P[i]]);

        for(int i = 1; i < m; ++i)
            F[P[i+1]][P[i]] += fmin,
            F[P[i]][P[i+1]] -= fmin;

        flow += fmin * Dist[D];
    }
    printf("%d\n",flow);
}

int main()
{
    freopen("fmcm.in","rt",stdin);
    freopen("fmcm.out","wt",stdout);

    citire();
    flux();
}