Cod sursa(job #309067)

Utilizator mlazariLazari Mihai mlazari Data 29 aprilie 2009 16:02:04
Problema Cuplaj maxim in graf bipartit Scor 40
Compilator cpp Status done
Runda tot Marime 1.74 kb
#include<stdio.h>
#define NMAX 1001

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

int i,j,k=0,l=0,n,m,e,a,b,g1[NMAX],g2[NMAX],r[NMAX],h[NMAX],p[NMAX];
lista* v1[NMAX];
lista* v2[NMAX];
lista *q,*qm;

void sw(int &a,int &b) { int c=a; a=b; b=c; }
  
void swap(int a,int b) {
  p[h[a]]=b;
  p[h[b]]=a;
  sw(h[a],h[b]);
}

void upheap(int x) {
  while(x>1)
   if(g1[h[x]]<g1[h[x>>1]]) { swap(x,x>>1); x=x>>1; } else x=1;
}

void downheap(int x) {
  int f;
  while((f=x<<1)<=l) {
    if((f+1<=l)&&(g1[h[f]]>g1[h[f+1]])) f++;
    if(g1[h[x]]>g1[h[f]]) { swap(x,f); x=f; } else x=l;
  }
}

void addheap(int x) {
  h[++l]=x;
  p[x]=l;
  upheap(l);
}

int minheap() {
  int rez=h[1];
  swap(1,l--);
  downheap(1);
  return rez;
}

void init() {
  int i;
  for(i=1;i<=n;i++) { v1[i]=NULL; g1[i]=0; r[i]=0; }
  for(i=1;i<=m;i++) { g2[i]=0; v2[i]=NULL; }
}

void add(int a,int b) {
  lista *q=new lista;
  q->x=b;
  q->next=v1[a];
  v1[a]=q;
  g2[b]++;
  q=new lista;
  q->x=a;
  q->next=v2[b];
  v2[b]=q;
  g1[a]++;
}

int main() {
  freopen("cuplaj.in","r",stdin);
  freopen("cuplaj.out","w",stdout);
  scanf("%d %d %d",&n,&m,&e);
  init();
  for(i=0;i<e;i++) {
    scanf("%d %d",&a,&b);
    add(a,b);
  }
  for(i=1;i<=n;i++) addheap(i);
  while(l) {
    q=qm=v1[j=minheap()];
    while(q) {
     if(!g2[qm->x] || g2[q->x]&&(g2[q->x]<g2[qm->x])) qm=q;
     q=q->next;
    }
    if(qm && g2[qm->x]) {
      r[j]=qm->x; g2[qm->x]=0; k++;
      q=v2[r[j]];
      while(q) {
	if(q->x!=j) {
	  g1[q->x]--;
	  upheap(p[q->x]);
	  if(!g1[h[1]]) minheap();
	}
	q=q->next;
      }
    }
  }
  printf("%d\n",k);
  for(i=1;i<=n;i++)
   if(r[i]) printf("%d %d\n",i,r[i]);
  fclose(stdout);
  return 0;
}