Cod sursa(job #2757192)

Utilizator gabrielinelusGabriel-Robert Inelus gabrielinelus Data 4 iunie 2021 13:25:31
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.55 kb
#include <cstdio>
#include <vector>
#include <bitset>

using namespace std;
vector<vector<int>> Graph; // Graph[i] = the neighbours (on the right) of the left node i.
vector<int> Left; // Left[i] = who's i's match on the left, i being on the right
vector<int> Right; // Right[i] = who's i's match on the right, i being on the left
bitset<10005> used;

bool findMatch(int k) {
  if (used[k])
    return false;
  used[k] = true;

  for (auto v: Graph[k])
    if (Left[v] == -1) {// v is unamtched and is a neighbour of k
      Right[k] = v;
      Left[v] = k;
      return true;
    }
  // There's no free neighbour, look for alternating path

  for (auto v: Graph[k])
    if (findMatch(Left[v])) {
      Right[k] = v;
      Left[v] = k;
      return true;
    }
  // We failed to extend
  return false;
}

int main()
{
  freopen("cuplaj.in", "r", stdin);
  freopen("cuplaj.out", "w", stdout);

  int L, R, M;
  scanf("%d%d%d", &L, &R, &M);

  Graph.resize(L);
  Left.resize(R);
  Right.resize(L);

  fill(Left.begin(), Left.end(), -1);
  fill(Right.begin(), Right.end(), -1);

  for (int i = 0; i < M; ++i) {
    int l, r;
    scanf("%d%d", &l, &r);
    --l;
    --r;
    Graph[l].emplace_back(r);
  }
  
  int matches = 0;
  bool madeProgress = true;
  while (madeProgress) {
    madeProgress = false;
    used = 0;

    for (int i = 0; i < L; ++i)
      if (Right[i] == -1 && findMatch(i)) {
	++matches;
	madeProgress = true;
      }
  }

  printf("%d\n", matches);
  for (int i = 0; i < L; ++i)
    if (Right[i] != -1)
      printf("%d %d\n", i + 1, Right[i] + 1);
  
  return 0;
}