Cod sursa(job #584253)

Utilizator Mirc100Mircea Octavian Mirc100 Data 24 aprilie 2011 20:34:11
Problema Cuplaj maxim in graf bipartit Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.17 kb
#include<fstream>
#include<iostream>
using namespace std;


struct nod{
   int inf;
   nod *adr;
} **ls,*s,*p;
//vector de liste

/*inserarea la sfarsitul unei liste
!! inceputul si sfarsitul listei trebuie transmise prin referinta, cu &
*/

 int n,m,i,j,x,y;
 long e;
 int *match,*tata;
   
void insert(nod *&prim, int v){
   nod *q;
   q=new nod;// se aloca un element al listei
   q->inf=v;
   q->adr=prim;
   prim=q;
}

/*void afis(nod *p){
   while(p){
      cout<<(p->inf-n+1)<<" ";//se readuc etichetele varfurilor intre 1 si n, de aceea se aduna 1 la informatie
      p=p->adr;
   }
   cout<<endl;
}*/

int extract(nod* &p){
    int x=p->inf;
    nod* q=p;
    p=p->adr;
    delete q;
    return x;
}
    
int main(){
   fstream f("cuplaj.in",ios::in);
   fstream g("cuplaj.out",ios::out); 
           
   if(f==NULL){
       cout<<"probleme deschidere fisier";
       return 0;
   }
   
   f>>n;
   f>>m;
   f>>e;
   ls=new nod*[n+m+1];
   for(i=0;i<=n+m;i++)
       ls[i]=NULL;
   
   for(i=0;i<e;i++){
      f>>x>>y;
      insert(ls[x-1],y+n-1);
      insert(ls[y+n-1],x-1);
   }
   f.close();
   /*for(i=0;i<n+m;i++){
      cout<<(i+1)<<": ";
      afis(ls[i]);
     
   }*/
  s=NULL;
   //culpaj arbitrar-greedy
   match=new int[n+m];
   tata=new int[n+m];
   int u;
   for(i=0;i<n+m;i++)
      match[i]=tata[i]=-1;
   for(i=0;i<n;i++){
       for(nod* p=ls[i];p;p=p->adr)
           if(match[p->inf]==-1){
                match[p->inf]=i;
                match[i]=p->inf;
                break;                
           }
       if(match[i]==-1)
           insert(s,i);//toate vfle nesaturate initia
}            
 /*  for(i=0;i<n;i++)
       cout<<i<<" "<<match[i]<<endl;
   */
   
//cout<<s->inf<<s->adr->inf;
   int ok=1;
   while(s!=0){
       for(i=0;i<n+m;i++)
            tata[i]=-1;
        u=s->inf;
       // cout<<"radacina"<<u<<endl;
        extract(s);
       // cout<<"nivel";
        if(match[u]==-1){
           nod* coada=0; 
           insert(coada,u);
           do{
             int x=extract(coada);    
            // cout<<x<<" ";  
             for(p=ls[x];p;p=p->adr){
            // cout<<p->inf;
             if(tata[p->inf]==-1)//nevizitat
                 if(match[p->inf]>=0){// cuplat
                   tata[p->inf]=x;
                   int z=match[p->inf];
                   insert(coada,z);  
                   tata[z]=p->inf;
                 }
                 else
                 if(x!=u){//ex vf nesaturat
                  int y=p->inf;
                  while(x>=0){
                      match[x]=y;
                      match[y]=x;
                      if(tata[x]>=0) match[tata[x]]=-1;
                      y=tata[x];
                      if(y>=0) x=tata[y];
                      else x=-1;
                 }            
               } 
               }
           }while(coada); 
           }    
       }      
       //cout<<endl<<endl;
       for(int i=0;i<n;i++)
           if(match[i]>=0)
            g<<(i+1)<<" "<<(match[i]+1-n)<<endl;               
     g.close();
     f.close();  
   //getch();
   
  
   return 1;
}