Cod sursa(job #2973392)

Utilizator cadmium_Voicu Mihai-Valeriu cadmium_ Data 31 ianuarie 2023 21:10:11
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.77 kb
#include <bits/stdc++.h>
#define all(x) (x).begin(),(x).end()
using namespace std;

#ifndef DLOCAL
  #define cin fin
  #define cout fout
  ifstream cin("cuplaj.in");
  ofstream cout("cuplaj.out");
#endif

using ll = long long;

//#define int ll
#define sz(x) ((int)(x).size())

using pii = pair<int,int>;
using tii = tuple<int,int,int>;

const int nmax = 1e5 + 5;

vector<int> g[nmax];
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

namespace Cuplaj {
  vector<int> g[nmax];
  vector<int> viz, l, r;
  void push(int a, int b) { g[a].emplace_back(b); }
  bool push(int node) {
    if(viz[node] == 1) return 0;
    viz[node] = 1;
    for(auto x : g[node]) if(l[x] == -1) {
        r[node] = x;
        l[x] = node;
        return 1;
      }
    
    for(auto x : g[node]) if(push(l[x])) {
        r[node] = x;
        l[x] = node;
        return 1;
      }
    return 0;
  }
  vector<pii> get(int n) {
    l.resize(n);
    r.resize(n);
    viz.resize(n);
    fill(all(l), -1);
    fill(all(r), -1);
    while(1) {
      bool ok = 0;
      fill(all(viz), 0);
      for(int i = 0; i < n; i++)
        if(r[i] == -1)
          ok |= push(i);
      if(ok == 0) break;
    }
    
    vector<pii> edg;
    for(int i = 0; i < n; i++) {
      if(r[i] != -1)
        edg.emplace_back(i, r[i]);
    }
    return edg;
  }
}

signed main() {
  int n, m, E;
  cin >> n >> m >> E;
  vector<pii> edg(E);
  for(auto &[a, b] : edg) cin >> a >> b;
  random_shuffle(all(edg), [&](int x) { return rng() % x; });
  for(auto [a, b] : edg)
    --a,
    --b,
    Cuplaj::push(a, b + n);
  
  auto v = Cuplaj::get(n + m);
  cout << sz(v) << '\n';
  for(auto [a, b] : v)
    cout << a + 1 << ' ' << b + 1 - n << '\n';
}

/**
      Vom spune că toamna a venit... foarte trist -
-- George Bacovia, Scântei galbene
*/