Cod sursa(job #1845234)

Utilizator TincaMateiTinca Matei TincaMatei Data 11 ianuarie 2017 02:37:43
Problema Cuplaj maxim in graf bipartit Scor 42
Compilator cpp Status done
Runda Arhiva educationala Marime 2.54 kb
#include <cstdio>

const int MAX_N = 10000;
const int MAX_M = 100000;

int last[2][1+MAX_N], next[1+2*MAX_M], mc[1+2*MAX_M];
int cuplat[2][1+MAX_N], q1[1+2*MAX_N], q2[1+2*MAX_N], st, dr, papa[2][1+MAX_N];
bool viz[2][1+MAX_N];

int cuplaj;

bool rise(int node) {
  int gr = 1;
  int g, n;
  g = 1-gr; n = papa[gr][node];
  while(cuplat[g][n] > 0) {
    n = papa[g][n];
    g = 1 - g;
  }
  if(papa[g][n] == 0 && cuplat[g][n] == 0) {
    while(node > 0) {
      cuplat[gr][node] = papa[gr][node];
      cuplat[1-gr][papa[gr][node]] = node;
      node = papa[1 - gr][papa[gr][node]];
    }
    cuplaj++;
    return true;
  }
  return false;
}

inline bool augment(int n, int m) {
  int node, gr;
  bool ok = false;
  st = dr = 0;
  for(int i = 1; i <= n; ++i) {
    viz[0][i] = false;
    papa[0][i] = 0;
    if(cuplat[0][i] == 0) {
      q1[dr] = i;
      q2[dr] = 0;
      ++dr;
      viz[0][i] = true;
    }
  }
  for(int i = 1; i <= m; ++i) {
    viz[1][i] = false;
    papa[1][i] = 0;
  }

  while(dr - st > 0) {
    node = q1[st];
    gr = q2[st];
    ++st;
    if(gr == 1 && !viz[0][cuplat[1][node]]) {
      viz[0][cuplat[1][node]] = true;
      q1[dr] = cuplat[1][node];
      q2[dr] = 0;
      ++dr;
      papa[0][cuplat[1][node]] = node;
    } else if(gr == 0) {
      int i = last[0][node];
      bool augm = false;
      while(i != 0 && !augm) {
        if(cuplat[1][mc[i]] == 0 && !viz[1][mc[i]]) {
          papa[1][mc[i]] = node;
          viz[1][mc[i]] = true;
          augm = true;
        }
        if(!augm) i = next[i];
      }
      if(augm && rise(mc[i])) {
        ok = true;
      } else if(!augm) {
        int i = last[0][node];
        while(i != 0) {
          if(!viz[1][mc[i]]) {
            papa[1][mc[i]] = node;
            q1[dr] = mc[i];
            q2[dr] = 1;
            ++dr;
            viz[1][mc[i]] = true;
          }
          i = next[i];
        }
      }
    }
  }
  return ok;
}

inline void addM(int gr, int a, int b, int id) {
  next[id] = last[gr][a];
  last[gr][a] = id;
  mc[id] = b;
}

int main() {
  int n, m, e, a, b;
  FILE *fin = fopen("cuplaj.in", "r");
  fscanf(fin, "%d%d%d", &n, &m, &e);
  for(int i = 0; i < e; ++i) {
    fscanf(fin, "%d%d", &a, &b);
    addM(0, a, b, i * 2 + 1);
    addM(1, b, a, i * 2 + 2);
  }
  fclose(fin);

  while(augment(n, m));

  FILE *fout = fopen("cuplaj.out", "w");
  fprintf(fout, "%d\n", cuplaj);
  for(int i = 1; i <= n; ++i)
    if(cuplat[0][i] > 0)
      fprintf(fout, "%d %d\n", i, cuplat[0][i]);
  fclose(fout);
  return 0;
}
//autismul se manifesta prin cai misterioase
//penalitatea si-a spus cuvantul