Cod sursa(job #782898)

Utilizator visanrVisan Radu visanr Data 30 august 2012 14:56:00
Problema Flux maxim de cost minim Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 3.87 kb
#include <fstream>
#include <cmath>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;


#define nmax 360
#define inf 0x3f3f3f3f
#define ll long long
#define mp make_pair

vector<int> G[nmax];
bool InQueue[nmax];
int Cost[nmax][nmax], N, M, X, Y, C, S, D, Z, Dist[nmax], Sum, Flag, OK;
int CurrentFlow[nmax][nmax], Capacity[nmax][nmax], Father[nmax];


int BellmanFord()
{
     int node, i;
     queue<int> Q;
     Q.push(S);
     for(i = 1; i <= N; i++) Dist[i] = inf;
     Dist[S] = 0;
     while(!Q.empty())
     {
                      node = Q.front();
                      Q.pop();
                      if(node == D) break;
                      InQueue[node] = false;
                      vector<int> :: iterator it;
                      Flag = 1;
                      for(it = G[node].begin(); it != G[node].end(); ++it)
                             if(Capacity[node][*it] > CurrentFlow[node][*it])
                                           if(Dist[node] + Cost[node][*it] < Dist[*it])
                                           {
                                                         Dist[*it] = Dist[node] + Cost[node][*it];
                                                         Flag = 0;
                                                         if(!InQueue[*it])
                                                         {
                                                                          InQueue[*it] = 1;
                                                                          Q.push(*it);
                                                         }
                                           }
                      if(Flag) break;
     }
     Sum = Dist[D];
     return Flag;
}

int Dijkstra()
{
    vector<int> :: iterator it;
    priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > Q;
    int i, j;
    for(i = 1; i <= N; i++)
          for(it = G[i].begin(); it != G[i].end(); ++it)
                   if(Dist[i] != inf && Dist[*it] != inf)
                              Cost[i][*it] += Dist[i] - Dist[*it];
    for(i = 1; i <= N; i++)
          Dist[i] = inf, Father[i] = -1;
    Dist[S] = 0;
    Q.push(mp(0, S));
    while(!Q.empty())
    {
                     int node = Q.top().second;
                     Q.pop();
                     for(it = G[node].begin(); it != G[node].end(); ++it)
                            if(Capacity[node][*it] > CurrentFlow[node][*it] && Dist[node] + Cost[node][*it] < Dist[*it])
                            {
                                      Dist[*it] = Dist[node] + Cost[node][*it];
                                      Father[*it] = node;
                                      Q.push(mp(Dist[*it], *it));
                            }
    }
    if(Dist[D] != inf)
    {
               int minFlow = inf;
               OK = 1;
               for(i = D; i != S; i = Father[i])
                     minFlow = min(minFlow, Capacity[Father[i]][i] - CurrentFlow[Father[i]][i]);
               for(i = D; i != S; i = Father[i])
               {
                     CurrentFlow[Father[i]][i] += minFlow;
                     CurrentFlow[i][Father[i]] -= minFlow;
               }
               Sum += Dist[D];
               return minFlow * Sum;
    }
    return 0;
}

ll Flux()
{
     ll ans = 0;
     OK = 1;
     while(OK)
     {
              OK = 0;
              ans += Dijkstra();
     }
     return ans;
}

int main()
{
    ifstream in("fmcm.in");
    ofstream out("fmcm.out");
    int i, j;
    in >> N >> M >> S >> D;
    for(i = 1; i <= M; i++)
    {
          in >> X >> Y >> C >> Z;
          G[X].push_back(Y);
          G[Y].push_back(X);
          Capacity[X][Y] = C;
          Cost[X][Y] = Z;
          Cost[Y][X] = -Z;
    }
    BellmanFord();
    out << Flux() << "\n";
    return 0;
}