Cod sursa(job #789717)

Utilizator visanrVisan Radu visanr Data 19 septembrie 2012 00:03:36
Problema Flux maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 3.93 kb
#include <fstream>
#include <cmath>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;

#define PII pair<int, int> 
#define nmax 360
#define inf 0x3f3f3f3f
#define mp make_pair
#define pb push_back

priority_queue<PII, vector<PII>, greater<PII> > P;

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


void BellmanFord()
{
     int node, i;
     for(i = 1; i <= N; i++) Dist[i] = inf;
     Dist[S] = 0;
     queue<int> Q;
     InQueue[S] = 1;
     Q.push(S);
     while(!Q.empty())
     {
                      node = Q.front();
                      Q.pop();
                      InQueue[node] = false;
                      for(vector<PII> :: iterator it = G[node].begin(); it != G[node].end(); ++it)
                      {
                                      int nodvcn = it -> first;
                                      int cost = it -> second;
                                      if(Dist[nodvcn] > Dist[node] + cost && Capacity[node][nodvcn] > CurrentFlow[node][nodvcn])
                                      {
                                                      Dist[nodvcn] = Dist[node] + cost;
                                                      if(!InQueue[nodvcn])
                                                      {
                                                                          InQueue[nodvcn] = 1;
                                                                          Q.push(nodvcn);
                                                      }
                                      }
                      }
     }
}

void Update()
{
     int i, j;
     for(i = 1; i <= N; i++)
          for(vector<PII> :: iterator it = G[i].begin(); it != G[i].end(); ++it)
          {
                          int nodvcn = it -> first, cost = it -> second;
                          it -> second = cost + Dist[i] - Dist[nodvcn];
          }   
}

bool Dijkstra()
{
    int i, node;      
    for(i = 1; i <= N; i++)
          Dist[i] = inf;
    Dist[S] = 0;
    P.push(mp(0, S));
    while(!P.empty())
    {
                     node = P.top().second;
                     P.pop();
                     for(vector<PII> :: iterator it = G[node].begin(); it != G[node].end(); ++it)
                     {
                            int nodvcn = it -> first, cost = it -> second;
                            if(Dist[nodvcn] > Dist[node] + cost && Capacity[node][nodvcn] > CurrentFlow[node][nodvcn])
                            {
                                      Dist[nodvcn] = Dist[node] + cost;
                                      Father[nodvcn] = node;
                                      P.push(mp(Dist[nodvcn], nodvcn));
                            }
                     }
    }
    return Dist[D] != inf;
}


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].pb(mp(Y, Z));
          G[Y].pb(mp(X, -Z));
          Capacity[X][Y] = C;
    }
    BellmanFord(); 
    Update();
    Sum = Dist[D];
    int ans = 0;
    while(Dijkstra())
    {
                      int minFlow = inf, node;
                      for(node = D; node != S; node = Father[node])
                               minFlow = min(minFlow, Capacity[Father[node]][node] - CurrentFlow[Father[node]][node]);
                      for(node = D; node != S; node = Father[node])
                      {
                               CurrentFlow[Father[node]][node] += minFlow;
                               CurrentFlow[node][Father[node]] -= minFlow;
                      }
                      Sum += Dist[D];
                      ans += Sum * minFlow;
                      Update();
    }
    out << ans;
    return 0;
}