Cod sursa(job #2085523)

Utilizator MiricaMateiMirica Matei MiricaMatei Data 10 decembrie 2017 12:27:18
Problema Flux maxim de cost minim Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 2.64 kb
#include <bits/stdc++.h>

using namespace std;

const int INF = (1LL << 31) - 1;
const int MAX_N = 350;

typedef pair<int, int> p;

vector<int>G[MAX_N + 5];
int nrv[MAX_N + 5];
bool inc[MAX_N + 5];
int dist[MAX_N + 5];
int from[MAX_N + 5];
bool muchie[MAX_N + 5][MAX_N + 5];
int cr[MAX_N + 5][MAX_N + 5];
int cost[MAX_N + 5][MAX_N + 5];
int cost1[MAX_N + 5][MAX_N + 5];

int dijkstra(int s, int d, int n) {
  for (int i = 1; i <= n; ++i)
    dist[i] = INF;

  priority_queue<p>pq;
  pair<int, int>st = make_pair(0, s);
  pq.push(st);
  dist[s] = 0;
  while (!pq.empty() && dist[d] == INF) {
    p aux = pq.top();
    pq.pop();
    for (auto it:G[aux.second]) {
      if (dist[it] == INF && cr[aux.second][it] > 0) {
        dist[it] = cost1[aux.second][it] + aux.first;
        from[it] = aux.second;
        p aux1 = make_pair(dist[it], it);
        pq.push(aux1);
      }
    }
  }
  return dist[d];
}

int fmcm(int s, int d, int n) {
  int ans = 0, dm;
  dm = dijkstra(s, d, n);
  while (dm != INF) {
    int aux = INF;
    int node = d;
    while (node != s) {
      aux = min(aux, cr[from[node]][node]);
      node = from[node];
    }
    node = d;
    dm = 0;
    while (node != s) {
      dm += cost[from[node]][node];
      cr[from[node]][node] -= aux;
      cr[node][from[node]] += aux;
      node = from[node];
    }
    ans += dm * aux;
    dm = dijkstra(s, d, n);
  }
  return ans;
}

int main() {
  freopen("fmcm.in", "r", stdin);
  freopen("fmcm.out", "w", stdout);

  int n, m, s, d;
  scanf("%d%d%d%d", &n, &m, &s, &d);
  for (int i = 1; i <= m; ++i) {
    int u, v, c, cst;
    scanf("%d%d%d%d", &u, &v, &c, &cst);
    G[u].push_back(v);
    G[v].push_back(u);
    cr[u][v] = c;
    muchie[u][v] = 1;
    cost[u][v] = cst;
    cost[v][u] = -cst;
  }

  for (int i = 1; i <= n; ++i) {
    dist[i] = INF;
    nrv[i] = 0;
    inc[i] = 0;
  }
  inc[s] = 1;
  from[s] = s;
  nrv[s] = 1;
  dist[s] = 0;
  queue<int>q;
  q.push(s);
  while (!q.empty() && nrv[q.front()] < n) {
    int node = q.front();
    q.pop();
    inc[node] = 0;
    for (auto it:G[node]) {
      if (cr[node][it] > 0 && dist[node] + cost[node][it] < dist[it]) {
        from[it] = node;
        dist[it] = dist[node] + cost[node][it];
        if (inc[it] == 0) {
          inc[it] = 1;
          q.push(it);
          nrv[it]++;
        }
      }
    }
  }

  for (int i = 1; i <= n; ++i)
    for (int j = 1; j <= n; ++j)
      if (muchie[i][j]) {
        cost1[i][j] = cost[i][j] + dist[i] - dist[j];
        cost1[j][i] = -cost1[i][j];
      }

  printf("%d\n", fmcm(s, d, n));

  return 0;
}