Cod sursa(job #1937824)

Utilizator DjokValeriu Motroi Djok Data 24 martie 2017 12:09:48
Problema Flux maxim de cost minim Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 2.09 kb
#include <bits/stdc++.h>
using namespace std;

const int INF = 1e9 + 69 * 69;

int i, n, m, start, final, x, y, rs, cost[355][355], cap[355][355], oldD[355], realD[355], d[355], tata[355];
bool viz[355];
vector<int> lda[355];

void bfs() {
  for(int i = 1; i <= n; ++i) oldD[i] = INF;
  queue<int> q;
  oldD[start] = 0; viz[start] = 1;
  for(q.push(start); !q.empty(); q.pop()) {
    int front = q.front();
    viz[front] = 0;
    for(auto to : lda[front]) {
      if(!cap[front][to] || oldD[to] < oldD[front] + cost[front][to]) continue;
      oldD[to] = oldD[front] + cost[front][to];
      if(!viz[to]) q.push(to), viz[to] = 1;
    }
  }
}

bool dijkstra() {
  memset(d, 0x3f, sizeof(d));

  d[start] = 0; realD[start] = 0;
  priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;

  for(q.push(make_pair(d[start], start)); !q.empty();) {
    pair<int, int> now = q.top();
    q.pop();

    if(d[now.second] != now.first) continue;

    for(auto to : lda[now.second]) {
      if(!cap[now.second][to]) continue;
      int aux = d[now.second] + cost[now.second][to] + oldD[now.second] - oldD[to];
      if(d[to] <= aux) continue;

      d[to] = aux;
      realD[to] = realD[now.second] + cost[now.second][to];
      tata[to] = now.second;
      q.push(make_pair(d[to], to));
    }
  }

  memcpy(oldD, realD, sizeof(d));

  if(d[final] > 1e9) return 0;

  int addFlow = INF, toPay = 0;

  for(int i = final; i != start; i = tata[i]) {
    addFlow = min(addFlow, cap[tata[i]][i]);
    toPay += cost[tata[i]][i];
  }

  rs += addFlow * toPay;

  for(int i = final; i != start; i = tata[i]) {
    cap[tata[i]][i] -= addFlow;
    cap[i][tata[i]] += addFlow;
  }

  return 1;
}

int main() {
  ifstream cin("fmcm.in");
  ofstream cout("fmcm.out");
  ios_base::sync_with_stdio(0);

  for(cin >> n >> m >> start >> final; m; --m) {
    cin >> x >> y;
    lda[x].push_back(y);
    lda[y].push_back(x);
    cin >> cap[x][y] >> cost[x][y];
    cost[y][x] = -cost[x][y];
  }

  for(bfs(); dijkstra(););

  cout << rs << '\n';

  return 0;
}