Cod sursa(job #993258)

Utilizator Impaler_009Mihai Nitu Impaler_009 Data 3 septembrie 2013 16:01:27
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.68 kb
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>

#define maxn 351
#define inf 350001
#define vint vector<int>::iterator

using namespace std;

ifstream fin("fmcm.in");
ofstream fout("fmcm.out");

//general
vector <int> G[maxn];
int C[maxn][maxn],Cost[maxn][maxn],F[maxn][maxn];
int n,m,s,d,a,b,c,z,flowcost,flow;

//for Bellman-Ford
queue <int> Q;
int D[maxn]; bool viz[maxn];

//for Dijkstra
priority_queue <pair<int,int>, vector<pair<int,int> >, greater <pair<int,int> > > H;
int path[maxn],old_d[maxn],real_d[maxn];

bool dijkstra ()
{
    for (int i=1; i<=n; ++i) D[i]=inf, viz[i]=0;
    D[s] = 0;

    H.push (make_pair(0,s));

    while (!H.empty())
    {
        int x = H.top().second, dist = H.top().first;
        H.pop();

        if (viz[x]) continue;
        viz[x]=1;

        for (vint it = G[x].begin(); it!=G[x].end(); ++it)
        {
            if (C[x][*it]==F[x][*it]) continue;

            int cst = D[x] + Cost[x][*it] + old_d[x] - old_d[*it];

            if (cst < D[*it])
            {
                D[*it] = cst;
                real_d[*it] = real_d[x] + Cost[x][*it];
                path[*it] = x;

                H.push (make_pair(D[*it],*it));
            }
        }

    }
    return d[D]!=inf;
}

void bellman_ford ()
{
    for (int i=1; i<=n; ++i) old_d[i]=inf;
    old_d[s]=0;

    Q.push(s);
    viz[s]=1;

    while (!Q.empty())
    {
        int x = Q.front();
        for (vint it = G[x].begin(); it!=G[x].end(); ++it)
        {
            if (C[x][*it]==F[x][*it]) continue;

            if (old_d[x] + Cost[x][*it] < old_d[*it])
            {
                old_d[*it] = old_d[x] + Cost[x][*it];
                if (!viz[*it])
                {
                    viz[*it]=1;
                    Q.push(*it);
                }
            }
        }
        viz[x] = 0;
        Q.pop();
    }
}

int main()
{
    fin>>n>>m>>s>>d;

    for (int i=1; i<=m; ++i)
    {
        fin>>a>>b>>c>>z;
        C[a][b] = c;
        Cost[a][b] = z;
        Cost[b][a] = -z;
        G[a].push_back(b);
        G[b].push_back (a);
    }

    bellman_ford ();

    flowcost=0,flow=0;


    while (dijkstra())
    {
        int minf = inf;

        for (int i = d; i!=s; i=path[i])
        {
            minf = min (minf,C[path[i]][i]-F[path[i]][i]);
        }

        flow += minf;
        flowcost += minf * real_d[d];

        for (int i = d; i!=s; i=path[i])
        {
            F[path[i]][i] += minf;
            F[i][path[i]] -= minf;
        }

        memcpy (old_d, real_d, sizeof(real_d));
    }

    fout<<flowcost;

    return 0;
}