Cod sursa(job #750673)

Utilizator blue_phoenixPosea Elena blue_phoenix Data 22 mai 2012 19:32:43
Problema Cuplaj maxim in graf bipartit Scor 80
Compilator cpp Status done
Runda Arhiva educationala Marime 1.65 kb
#include<cstring>
#include<fstream>
#include<vector>
using namespace std;
#define nmax 100010
vector <int> graf[nmax];
int n,m,e,st[nmax],dr[nmax];
bool viz[nmax];
//dr[i]=corespondentul din prima multime pt nodul i din a doua multime
int cuplez(int nod){//vreau sa aflu daca pot sa construiesc un lant m-alternant deschis incepand din nod/ din prima multime
   int y;
   if(viz[nod]==1)return 0;//daca nodul a fost deja vizitat-> deja am imbunatatit ceva la el?????
   viz[nod]=1;
   for(int i=0;i<graf[nod].size();i++){//nod e din prima multime
        //ii parcurg toti vecinii
	y=graf[nod][i];
	if(!st[y]||cuplez(st[y])){//daca nu-i corespunde nimeni din prima multime/ nodul y e nesaturat
        //sau ii corespunde eventual cineva, dar am reusit sa gasesc un lant m-alternat deschis
		dr[nod]=y;
		st[y]=nod;
                //am marcat faptul ca acum in cuplaj apare muchia (y,nod)
		return 1;
	}
   }
   return 0;
}

int main(){
  ifstream fin("cuplaj.in");
  ofstream fout("cuplaj.out");
  fin>>n>>m>>e;
  int a,b,i;
  for(i=0;i<e;i++){
	fin>>a>>b;
	graf[a].push_back(b);
  }
  int nr_muchii=0;
  bool ok=1;

  while(ok){//daca am reusit sa mai saturez un nod ciclul trecut mai continuu
    //in momentul in care nu am mai putut sa saturez nimic/ nu mai lanturi m-alternante deschise-> asta e (conform T. lui Berge)
    ok=0;
    memset(viz,0,n);
    for(i=1;i<=n;i++)
      if(dr[i]==0&&cuplez(i)==1){
       //daca am gasit un nod liber/nesaturat in Y/dreapta si am reusit sa construiesc un lant M-alternant deschis care incepe in elem i
	ok=1;
	nr_muchii++;
      }
  }
  fout<<nr_muchii<<"\n";
  for(i=1;i<=n;i++)
     if(dr[i])
	fout<<i<<" "<<dr[i]<<"\n";
   return 0;
}