Cod sursa(job #2689510)

Utilizator nicu_ducalNicu Ducal nicu_ducal Data 21 decembrie 2020 10:33:26
Problema Cuplaj maxim in graf bipartit Scor 80
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.13 kb
#include <bits/stdc++.h>
using namespace std;

template <typename T> ostream& operator<<(ostream &os, const vector<T> &v) { os << '{'; string sep; for (const auto &x : v) os << sep << x, sep = ", "; return os << '}'; }
template <typename A, typename B> ostream& operator<<(ostream &os, const pair<A, B> &p) { return os << '(' << p.first << ", " << p.second << ')'; }
using i64 = long long int;

const int INF = INT_MAX, MOD = 1e9 + 7;
const double EPS = 1e-9, PI = acos(-1);
const int dx[] = {0, 0, 0, -1, 1, -1, 1, 1, -1};
const int dy[] = {0, -1, 1, 0, 0, -1, 1, -1, 1};


/// Undirected/directed graph (for directed delete a push_back from the addEdge
/// Algorithm: Kuhn's algorithm for bipartite matchings (O(NM) or O(N^3) worst case)
struct Graph {
  vector<vector<int>> adj;
  vector<bool> marked;
  vector<int> parent, level, match;
  int n, n1, n2, match_num;

  Graph(int _n1 = 0, int _n2 = 0) {
    init(_n1, _n2);
  }

  void init(int _n1, int _n2) {
    n = _n1 + _n2;
    n1 = _n1, n2 = _n2;
    adj.resize(n1 + 1);
    marked.resize(n1 + 1, false);
    match.resize(n2 + 1, -1);
  }

  void addEdge(int u, int v) {
    adj[u].push_back(v);
    // adj[v].push_back(u);
  }

  bool KuhnDFS(int node) {
    if (marked[node]) return false;
    marked[node] = true;
    for (auto next: adj[node]) {
      if (match[next] == -1 or KuhnDFS(match[next])) {
        match[next] = node;
        return true;
      }
    }
    return false;
  }

  void Kuhn() {
    for (int node = 1; node <= n1; node++) {
      marked.assign(n1 + 1, false);
      if (KuhnDFS(node))
        match_num++;
    }
  };
};

int main() {
  ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
  /// mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

  ifstream cin("cuplaj.in");
  ofstream cout("cuplaj.out");
  
  int N1, N2, M;
  cin >> N1 >> N2 >> M;
  Graph graph(N1, N2);
  for (int i = 0; i < M; i++) {
    int u, v;
    cin >> u >> v;
    graph.addEdge(u, v);
  }

  graph.Kuhn();

  cout << graph.match_num << "\n";
  for (int i = 1; i <= N2; i++) {
    if (graph.match[i] != -1) {
      cout << graph.match[i] << " " << i << "\n";
    }
  }

  return 0;
}