Cod sursa(job #2808951)

Utilizator cristi_macoveiMacovei Cristian cristi_macovei Data 25 noiembrie 2021 18:47:22
Problema Cuplaj maxim in graf bipartit Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.06 kb
#define d(x) std::cout << x << std::endl
#define dm(msg, x) std::cout << msg << x << std::endl

#define all(a) a.begin(), a.end()
#define range(a, l, r) a.begin() + l, a.begin() + r
#define aall(a, n) a + 1, a + 1 + n
#define arange(a, l, r) a + l, a + r
	
#define maxself(a, b) a = std::max(a, b);
#define minself(a, b) a = std::min(a, b);

#define inout(f) std::ifstream in((f) + (std::string) ".in");std::ofstream out((f) + (std::string) ".out")

#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>

const int NMAX = 500;
const int GSIZE = 2 * NMAX + 2;

int source, sink;

std::vector<int> graph[GSIZE];
int cap[GSIZE][GSIZE];

std::queue<int> q;
int prev[GSIZE];

int match[1 + NMAX];

bool bfs() {
  memset(prev, -1, sizeof(prev));

  q.push(source);
  prev[source] = 0;

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

    for (int i : graph[node]) {
      if (cap[node][i] > 0 && prev[i] == -1) {
        prev[i] = node;

        if (i != sink)
          q.push(i);
      }
    }
  }

  return prev[sink] != -1;
}

int main() {
  inout("cuplaj");

  int n, m, e;
  in >> n >> m >> e;

  source = 0;
  sink = n + m + 1;

  for (int i = 1; i <= n ; ++i) {
    graph[source].push_back(i);
    cap[source][i] = 1;
  }

  while (e--) {
    int a, b;
    in >> a >> b;

    graph[a].push_back(n + b);
    cap[a][n + b] = 1;

    graph[n + b].push_back(a);
    cap[n + b][a] = 0;
  }
  
  for (int i = 1; i <= m; ++i) {
    graph[n + i].push_back(sink);
    cap[n + i][sink] = 1;
  }

  int flow = 0;
  while (bfs()) {
    ++flow;
    int current = sink;

    while (current != prev[current]) {
      cap[prev[current]][current] = 0;
      cap[current][prev[current]] = 1;

      if (current > n && current != sink)
        match[prev[current]] = current - n;

      current = prev[current];
    }
  }

  out << flow << '\n';
  for (int i = 1; i <= n; ++i) {
    if (match[i] != 0)
      out << i << ' ' << match[i] << '\n';
  }

  return 0;
}