Cod sursa(job #1167131)

Utilizator toranagahVlad Badelita toranagah Data 4 aprilie 2014 13:36:36
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.78 kb
#include <algorithm>
#include <bitset>
#include <fstream>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

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

#define len(x) int((x).size())
#define x first
#define y second

const int INF = 1 << 30;
const int MAX_N = 360;

int N, M, S, D;
vector<int> graph[MAX_N];
int flow[MAX_N][MAX_N];
int cap[MAX_N][MAX_N];
int cost[MAX_N][MAX_N];
int ans;

int dist[MAX_N];
int father[MAX_N];

void read(), solve(), print();
bool bellman_ford();
int cp(int a, int b);
void add_flow(int a, int b, int f);

int main() {
  read();
  solve();
  print();
  return 0;
}

void read() {
  fin >> N >> M >> S >> D;
  for (int i = 1, a, b, c, z; i <= M; i += 1) {
    fin >> a >> b >> c >> z;
    graph[a].push_back(b);
    graph[b].push_back(a);
    cost[a][b] = z;
    cost[b][a] = -z;
    cap[a][b] = c;
  }
}

void solve() {
  while (bellman_ford()) {
    int mn = INF;
    for (int x = D; x != S; x = father[x])
      mn = min(mn, cp(father[x], x));

    ans += dist[D] * mn;
    
    for (int x = D; x != S; x = father[x])
      add_flow(father[x], x, mn);
  }
}

bool bellman_ford() {
  queue<int> q;
  vector<bool> in_q(N + 1);
  q.push(S);
  fill(dist, dist + N + 1, INF);
  dist[S] = 0;

  while (!q.empty()) {
    int node = q.front();
    q.pop();

    in_q[node] = 0;

    for (auto x: graph[node]) {
      if (cp(node, x) > 0 && dist[node] + cost[node][x] < dist[x]) {
        father[x] = node;
        dist[x] = dist[node] + cost[node][x];

        if (!in_q[x]) {
          q.push(x);
          in_q[x] = 1;
        }
      }
    }
  }
  return dist[D] < INF;
}

inline int cp(int a, int b) {
  return cap[a][b] - flow[a][b];
}

inline void add_flow(int a, int b, int f) {
  flow[a][b] += f;
  flow[b][a] -= f;
}

void print() {
  fout << ans;
}