Cod sursa(job #761150)

Utilizator Theorytheo .c Theory Data 24 iunie 2012 22:49:32
Problema Flux maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.96 kb
#include<fstream>
#include<vector>
#include<queue>

using namespace std;

#define nmax 360
#define foreach(V) for(vector<int> :: iterator it = V.begin(); it != V.end(); it++)
#define ll long long
#define min(a,b) (a>b ? b : a)

const int inf  = 1<<30;

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

int N, M, C[nmax][nmax];//capacitate
int TT[nmax], cost[nmax][nmax], dist[nmax], S, D, sum, drum ;
int F[nmax][nmax];
vector<int> G[nmax];

struct cmp//pentru a putea mentine heapul ordonat la dijkstra(min-heap)
{
    bool operator()(const int &x, const int &y)const
    {
        return dist[x]>dist[y];
    }
};

void BellmanFord()
{
    queue <int> q;

    for(int i = 1; i <= N; i++)
        dist[i] = inf;

    dist[S] = 0;
    q.push(S);

    while( !q.empty() )
    {
        int nod = q.front();
        q.pop();
        foreach(G[nod])
        {
            int y = (*it);
            if(dist[nod] + cost[nod][y] < dist[y] && C[nod][y] > 0)
            {
                dist[y] = cost[nod][y] + dist[nod];
                q.push(y);
            }
        }
    }

    sum = dist[D];//costul cel mai bun de la sursa la destinatie

}



int Dijkstra()
{

    //Fac transformarile astfel incat sa am doar costuri pozitive pe arcekle active (capcitate> flux)
    priority_queue <int, vector<int>, cmp> q;

    q.push(S);

    for(int i = 1; i <= N ;i++)
        foreach(G[i])
            if(dist[i] != inf && dist[*it] != inf)
                cost[i][*it] += dist[i] - dist[*it];

    for(int i = 1; i <= N; i++)
    {
        dist[i] = inf;
        TT[i] = -1;
    }
    dist[S] = 0 ;

    while(!q.empty())
    {
        int x  = q.top();
        q.pop();
        foreach(G[x])
        {
            int v = *it;
            if(C[x][v] - F[x][v] > 0 && dist[x] + cost[x][v] < dist[v])
            {
                dist[v] = dist[x] + cost[x][v];
                TT[v] = x;
                q.push(v);
            }
        }

    }


   if(dist[D] != inf)//cat timp exista drum de la sursa la destinatie
   {
        int vmin = inf;
       drum = 1;

       for(int i = D; i != S; i = TT[i])
       vmin = min(vmin, C[TT[i]][i] - F[TT[i]][i]);

        for(int i = D;  i != S; i = TT[i])
        {
            F[TT[i]][i] += vmin;
            F[i][TT[i]] -= vmin;
        }

      sum+=dist[D];
      return vmin * sum;
   }
   return 0;

}
ll det_flux()
{
    ll rez = 0;
    drum = 1;

    while(drum)
    {
        drum = 0;
        rez += Dijkstra();
    }

    return rez;


}
void read()
{
    int x, y, z, cap;
    fin >>N>> M;
    fin>> S>> D;
    for(int i = 1; i <= M;i++)
    {
        fin >>x >> y>>cap>>z;
        G[x].push_back(y);
        G[y].push_back(x);
        cost[x][y] = z;
        cost[y][x] = -z;
        C[x][y] = cap;
    }
}

int main()
{
    read();
    BellmanFord();
    fout << det_flux();

    fin.close();
    return 0;

}