Cod sursa(job #2737944)

Utilizator StanSiBranBranSiStan StanSiBran Data 5 aprilie 2021 12:40:40
Problema Flux maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.33 kb
#include <bits/stdc++.h>
#define ll long long
#define ld long double

using namespace std;

const ll MOD = 1e9 + 7;
const ll INF = 1e9;

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

const int N = 400;
int n, m, c[N][N], flow[N][N], cost[N][N], S, D, par[N];
int dist[N], distTrue[N], distFalse[N];

vector<int>G[N];

bool dijkstra () {
  for (int i = 1; i <= n; i++)
    distFalse[i] = INF;
  distFalse[S] = 0;
  priority_queue<pair<int, int> > pq;
  pq.push({0, S});
  while (pq.size()) {
    auto p = pq.top();
    pq.pop();
    p.first = -p.first;
    if (distFalse[p.second] != p.first) 
      continue;
    for (auto it : G[p.second])
      if (flow[p.second][it] < c[p.second][it]) {
        if (p.first + cost[p.second][it] + dist[p.second] - dist[it] < distFalse[it]) {
          distFalse[it] = p.first + cost[p.second][it] + dist[p.second] - dist[it];
          distTrue[it] = distTrue[p.second] + cost[p.second][it];
          par[it] = p.second;
          pq.push({-distFalse[it], it});
        }
      }
  }
  for (int i = 1; i <= n; i++)
    dist[i] = distTrue[i];
  if (distFalse[D] == INF)
    return 0;
  return 1;
}

void bellman () {
  priority_queue<pair<int, int>>pq;
  for (int i = 1; i <= n; i++) {
    dist[i] = INF;
  }
  dist[S] = 0;
  pq.push({0, S});
  while (pq.size()) {
    auto p = pq.top();
    pq.pop();
    p.first = -p.first;
    if (dist[p.second] != p.first) 
      continue;
    for (auto it : G[p.second])
      if (flow[p.second][it] < c[p.second][it]) {
        if (p.first + cost[p.second][it] < dist[it]) {
          dist[it] = p.first + cost[p.second][it];
          pq.push({-dist[it], it});
        }
      }
  }
}

int main()
{
  fin >> n >> m >> S >> D;
  for (int i = 1; i <= m; i++) {
    int x, y, cap, z;
    fin >> x >> y >> cap >> z;
    cost[x][y] = z;
    cost[y][x] = -z;
    c[x][y] = cap;
    G[x].push_back(y);
    G[y].push_back(x);
  }
  int ans = 0;
  bellman();
  while (dijkstra()) {
    int fmin = INF;
    for (int nod = D; nod != S; nod = par[nod]) {
      fmin = min(fmin, c[par[nod]][nod] - flow[par[nod]][nod]);
    }
    ans += fmin * distTrue[D];
    for (int nod = D; nod != S; nod = par[nod]) {
      flow[par[nod]][nod] += fmin;
      flow[nod][par[nod]] -= fmin;
    }
  }
  fout << ans;
  return 0;
}