Cod sursa(job #2763150)

Utilizator Razvan48Capatina Razvan Nicolae Razvan48 Data 12 iulie 2021 00:24:19
Problema Flux maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.97 kb
#include <fstream>
#include <vector>
#include <climits>
#include <queue>
#include <cstring>
 
using namespace std;
 
const int NMAX = 350;
 
int n, m, start, dest;
 
vector<int> graf[1 + NMAX];
int capacitate[1 + NMAX][1 + NMAX];
int cost[1 + NMAX][1 + NMAX];
 
queue<int> q;
bool inCoada[1 + NMAX];
 
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
 
int distInitial[1 + NMAX];
int distDijkstra[1 + NMAX];
int distReala[1 + NMAX];
 
int tata[1 + NMAX];
 
void bellmanFord()
{
  for (int i = 1; i <= n; i++)
    distInitial[i] = INT_MAX;
 
  distInitial[start] = 0;
  q.emplace(start);
  inCoada[start] = true;
 
  while (!q.empty())
  {
    int nod = q.front();
    q.pop();
    inCoada[nod] = false;
 
    for (auto& vecin : graf[nod])
    {
      if (capacitate[nod][vecin] > 0 && distInitial[nod] + cost[nod][vecin] < distInitial[vecin])
      {
        distInitial[vecin] = distInitial[nod] + cost[nod][vecin];
 
        if (!inCoada[vecin] && vecin != dest)
        {
          q.emplace(vecin);
          inCoada[vecin] = true;
        }
      }
    }
  }
}
 
bool dijkstra()
{
  memset(tata, 0, sizeof(tata));
 
  for (int i = 1; i <= n; i++)
    distDijkstra[i] = INT_MAX;
 
  distDijkstra[start] = 0;
  distReala[start]    = 0;
  tata[start] = start;
  pq.emplace(0, start);
 
  while (!pq.empty())
  {
    int nod = pq.top().second;
    int distNod = pq.top().first;
    pq.pop();
 
    if (distNod > distDijkstra[nod]) continue;
 
    for (auto& vecin : graf[nod])
    {
      if (capacitate[nod][vecin] > 0 && distNod + distInitial[nod] + cost[nod][vecin] - distInitial[vecin] < distDijkstra[vecin])
      {
        distDijkstra[vecin] = distNod + distInitial[nod] + cost[nod][vecin] - distInitial[vecin];
        distReala[vecin]    = distReala[nod] + cost[nod][vecin];
        tata[vecin] = nod;
 
        if (vecin != dest)
          pq.emplace(distDijkstra[vecin], vecin);
      }
    }
  }
 
  memcpy(distInitial, distReala, sizeof(distInitial));
 
  return distDijkstra[dest] != INT_MAX;
}
 
int main()
{
  ifstream in("fmcm.in");
  ofstream out("fmcm.out");
 
  in >> n >> m >> start >> dest;
 
  for (int j = 1; j <= m; j++)
  {
    int x, y, c, z;
 
    in >> x >> y >> c >> z;
 
    graf[x].emplace_back(y);
    graf[y].emplace_back(x);
 
    capacitate[x][y] = c;
 
    cost[x][y] = z;
    cost[y][x] = -z;
  }
 
  bellmanFord();
 
  int sol = 0;
 
  while (dijkstra())
  {
    int capMinima = INT_MAX;
 
    for (int nodCrt = dest; nodCrt != tata[nodCrt]; nodCrt = tata[nodCrt])
    {
      capMinima = min(capMinima, capacitate[tata[nodCrt]][nodCrt]);
    }
 
    for (int nodCrt = dest; nodCrt != tata[nodCrt]; nodCrt = tata[nodCrt])
    {
      capacitate[tata[nodCrt]][nodCrt] -= capMinima;
      capacitate[nodCrt][tata[nodCrt]] += capMinima;
    }
 
    sol += distReala[dest] * capMinima;
  }
 
  out << sol << '\n';
 
  return 0;
}