Cod sursa(job #989967)

Utilizator toranagahVlad Badelita toranagah Data 27 august 2013 00:23:06
Problema Taramul Nicaieri Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.23 kb
#include <algorithm>
#include <fstream>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

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

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

int N;
vector<int> graph[MAX_N];
int residual_capacity[MAX_N][MAX_N];
int f[MAX_N][MAX_N];
int incoming[MAX_N];
int dist[MAX_N];
int source, sink;

int maxflow();
bool find_augmenting_path();

int main() {
  fin >> N;
  source = 2 * N + 1;
  sink = 2 * N + 2;
  for (int i = 1, x, y; i <= N; ++i) {
    fin >> x >> y;
    graph[source].push_back(i);
    graph[i].push_back(source);
    residual_capacity[source][i] = x;

    graph[i + N].push_back(sink);
    graph[sink].push_back(i + N);
    residual_capacity[i + N][sink] = y;
  }

  for (int i = 1; i <= N; ++i) {
    for (int j = 1; j <= N; ++j) {
      if (i == j) continue;
      graph[i].push_back(j + N);
      graph[j + N].push_back(i);
      residual_capacity[i][j + N] = 1;
    }
  }
  N = 2 * N + 2;

  fout << maxflow() << '\n';
  
  N = (N - 2) / 2;
  for (int i = 1; i <= N; ++i) {
    for (int j = 1; j <= N; ++j) {
      if (i == j) continue;
      if (f[i][j + N]) {
        fout << i << ' ' << j << '\n';
      }
    }
  }
  return 0;
}

int maxflow() {
  int result = 0;
  while (find_augmenting_path()) {
    int flow = INF;
    for (int node = sink; node != source; node = incoming[node]) {
      flow = min(flow, residual_capacity[incoming[node]][node]);
    }
    result += flow;
    
    for (int node = sink; node != source; node = incoming[node]) {
      residual_capacity[incoming[node]][node] -= flow;
      residual_capacity[node][incoming[node]] += flow;
      f[incoming[node]][node] += flow;
      f[node][incoming[node]] = -f[incoming[node]][node];
    }
  }
  return result;
}

bool find_augmenting_path() {
  fill(dist + 1, dist + N + 1, INF);
  queue<int> q;
  q.push(source);
  dist[source] = 0;

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

    for (auto next : graph[node]) {
      if (residual_capacity[node][next] > 0) {
        if (dist[node] + 1 < dist[next]) {
          dist[next] = dist[node] + 1;
          incoming[next] = node;
          q.push(next);

          if (next == sink) return true;
        }
      }
    }
  }
  return false;
}