Cod sursa(job #1513839)

Utilizator hrazvanHarsan Razvan hrazvan Data 30 octombrie 2015 00:38:19
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator c Status done
Runda Arhiva educationala Marime 2.61 kb
#include <stdio.h>
#define MAXN 10000
#define MAXM 100000
#define INF 2000000000
int ult[2 * MAXN], next[2 * MAXM], nod[2 * MAXM];
int pairst[MAXN], pairdr[MAXN];
int newdr[MAXN], dn, dist[2 * MAXN];
char tr[2 * MAXN];
int n, k;

inline void bfs(){
  int q[2 * MAXN], st = 0, dr = 0, i, min = INF, poz;
  for(i = 0; i < n + k; i++)
    dist[i] = -1;
  for(i = 0; i < n; i++){
    if(pairst[i] == -1){
      q[dr] = i;
      dr++;
      dist[i] = 0;
    }
  }
  dn = 0;
  while(st < dr){
    if((dist[q[st]] & 1) && pairdr[q[st] - n] != -1){
      q[dr] = pairdr[q[st] - n];
      dr++;
      dist[pairdr[q[st] - n]] = dist[q[st]] + 1;
    }
    else  if(dist[q[st]] + 1 <= min){
      poz = ult[q[st]];
      while(poz != -1){
        if(dist[nod[poz]] == -1){
          q[dr] = nod[poz];
          dr++;
          dist[nod[poz]] = dist[q[st]] + 1;
          if(pairdr[nod[poz] - n] == -1)
            min = dist[nod[poz]];
        }
        poz = next[poz];
      }
    }
    if(dist[q[st]] == min && pairdr[q[st] - n] == -1){
      newdr[dn] = q[st];
      dn++;
    }
    st++;
  }
}

void dfs(int x, char *gasit){
  tr[x] = 1;
  if(dist[x] == 0)
    *gasit = 1;
  else{
    if(!(dist[x] & 1))
      dfs(pairst[x] + n, gasit);
    else{
      int poz;
      poz = ult[x];
      while(poz != -1 && !(*gasit)){
        if(!tr[nod[poz]] && dist[nod[poz]] == dist[x] - 1)
          dfs(nod[poz], gasit);
        if(!(*gasit))
          poz = next[poz];
        if(*gasit){
          pairdr[x - n] = nod[poz];
          pairst[nod[poz]] = x - n;
        }
      }
    }
  }
}

void caut(){
  bfs();
  int i;
  for(i = 0; i < n + k; i++)
    tr[i] = 0;
  char x;
  for(i = 0; i < dn; i++){
    x = 0;
    dfs(newdr[i], &x);
  }
  if(dn == 0)
    return ;
  else
    caut();
}

int main(){
  FILE *in = fopen("cuplaj.in", "r");
  int m, i, x, y, dr = 0;
  fscanf(in, "%d%d%d", &n, &k, &m);
  for(i = 0; i < n; i++)
    pairst[i] = -1;
  for(i = 0; i < k; i++)
    pairdr[i] = -1;
  for(i = 0; i < n + k; i++)
    ult[i] = -1;
  for(i = 0; i < m; i++){
    fscanf(in, "%d%d", &x, &y);
    x--;  y--;
    y += n;
    nod[dr] = x;
    next[dr] = ult[y];
    ult[y] = dr;
    dr++;
    nod[dr] = y;
    next[dr] = ult[x];
    ult[x] = dr;
    dr++;
  }
  fclose(in);
  caut(n, k);
  FILE *out = fopen("cuplaj.out", "w");
  int nr = 0;
  for(i = 0; i < n; i++)
    if(pairst[i] != -1)
      nr++;
  fprintf(out, "%d\n", nr);
  for(i = 0; i < n; i++)
    if(pairst[i] != -1)
      fprintf(out, "%d %d\n", i + 1, pairst[i] + 1);
  fclose(out);
  return 0;
}