Cod sursa(job #2680252)

Utilizator retrogradLucian Bicsi retrograd Data 3 decembrie 2020 01:20:26
Problema Cuplaj maxim in graf bipartit Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.52 kb
#include <bits/stdc++.h>

using namespace std;
mt19937 rng(time(0));

vector<int> Match(vector<vector<int>>& graph) {
  int n = graph.size();
  vector<int> vis(n), mate(n, -1), order(n);
  auto mateup = [&](int a, int b) {
    int c = mate[b]; mate[a] = b; mate[b] = a;
    if (c != -1) mate[c] = -1;
    return c;
  };
  function<bool(int)> dfs = [&](int node) {
    if (vis[node]) return false;
    vis[node] = true;
    shuffle(graph[node].begin(), graph[node].end(), rng);
    for (auto vec : graph[node]) 
      if (mate[vec] == -1) 
        return mateup(node, vec), true;
    for (auto vec : graph[node]) {
      int old = mateup(node, vec);
      if (dfs(old))
        return true;
      mateup(old, vec);
    }
    return false;
  };
  iota(order.begin(), order.end(), 0);
  for (int rem = 1; rem; rem--) {
    shuffle(order.begin(), order.end(), rng);
    vis.assign(n, false);
    for (auto i : order)
      if (mate[i] == -1 && dfs(i))
        rem = 50; // (*)
  }
  return mate;
}

int main() {
  ifstream cin("cuplaj.in");
  ofstream cout("cuplaj.out");
  int n, m, k; cin >> n >> m >> k;
  vector<vector<int>> graph(n + m);
  for (int i = 0; i < k; ++i) {
    int a, b; cin >> a >> b; --a; --b;
    graph[a].push_back(b + n);
    graph[b + n].push_back(a);
  }
  auto mate = Match(graph);
  vector<pair<int, int>> sol;
  for (int i = 0; i < n; ++i)
    if (mate[i] != -1)
      sol.emplace_back(i, mate[i] - n);

  cout << sol.size() << '\n';
  for (auto itr : sol) 
    cout << itr.first + 1 << " " << itr.second + 1 << '\n';

  return 0;
}