Cod sursa(job #235011)

Utilizator marcelcodreaCodrea Marcel marcelcodrea Data 22 decembrie 2008 14:25:17
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.34 kb
#include <cstdio>
#define N 10001
#include <string>

struct nod {
  int x;
  nod *next;
};

nod* a[N];
int n, m, E;
int l[N], r[N];
bool use[N];

inline void add(int i, int j) { // adauga in stiva de vecini
  nod* p = new nod;
  p->x = j;
  p->next = a[i];
  a[i] = p;
}

void read() {
  int p, q;

  freopen("cuplaj.in","r",stdin);
  scanf("%d %d %d\n", &n, &m, &E);
  while (E--) {
    scanf("%d %d\n", &p, &q);
    add(p, q);
  }
}

inline bool pairup (int i) {
  nod* j;

  if (use[i])
    return 0;
  use[i] = 1;
  for (j = a[i]; j; j = j->next) // pentru fiecare vecin al lui i
    if (!l[j->x]) { // vecinul nu are pereche in stanga ?
      l[j->x] = i;
      r[i] = j->x;
      return 1;
    }
  for (j = a[i]; j; j = j->next)
     if (pairup(l[j->x])) { // Stim ca j->x are pereche in stanga.
      l[j->x] = i;
      r[i] = j->x;
      return 1;
    }
  return 0;
}

void solve() {
  int flow = 0, ok = 1, i;

  while (ok) {
    ok = 0;
    memset(use, 0, sizeof(use));
    for (i = 1; i <= n; ++i)
      if (!r[i]) // nu are pereche in dreapta ?
        if (pairup(i))
          ++flow, ok = 1;
  }
  freopen("cuplaj.out", "w", stdout);
  printf("%d\n", flow);
  for (i = 1; i <= n; ++i)
    if (r[i])
      printf("%d %d\n", i, r[i]);
}

int main() {
  read();
  solve();
  return 0;
}