Cod sursa(job #1549765)

Utilizator vasiliu.alexandruVasiliu Alexandru vasiliu.alexandru Data 12 decembrie 2015 19:00:06
Problema Cuplaj maxim in graf bipartit Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 1.61 kb
#include <iostream>
#include <fstream>

using namespace std;

ifstream f("cuplaj.in");
ofstream g("cuplaj.out");


int l[20000]={0};
int c[20000];
int viz[20000];
short v[20000][20000];
int n,m,E;

void read()
{
f>>n>>m>>E;
int x,y;

for(int i=1;i<=E;i++)
   {f>>x>>y;
     y=n+y;
     l[x]++;
     v[x][l[x]]=y;
     //cout<<x<<" "<<y<<endl;
   }
}

void afisare()
{int i,j,nr=0;;
for(i=1;i<=n;i++)
        if(c[i]!=0) nr++;
g<<nr<<"\n";
for(i=1;i<=n;i++)
        if(c[i]!=0)
          {if(i>n) i=i-n;
           if(c[i]>n) c[i]=c[i]-n;
           g<<i<<" "<<c[i]<<"\n";
          }
}

void GenCuplaj()//Greedy
{
int i,j,k;
for(i=1;i<=n;i++)
    {j=1;
     if(c[i]==0)
       {while(j<=l[i])
          {k=v[i][j];//vecinul j al lui i
           if(c[k]==0)
                {c[v[i][j]]=i;c[i]=v[i][j]; break;}
           j++;
          }
        }
    }
}

void reset()
{for(int i=1;i<=n+m;i++) viz[i]=0;
}

int dfs(int i)
{
viz[i]=1;
int j;
for(j=1;j<=l[i];j++)
    {int k;
     k=v[i][j];
     if(viz[k]==1 || c[i]==k) continue;

     if(c[k]==0)
        { c[k]=i;
          c[i]=k;
          viz[k]=1;
          return 1;
         }

     viz[k]=1;

      if(dfs(c[k]))
              {c[i]=k;
               c[k]=i;
               return 1;
              }

    }//sf for
return 0;
}


void solve()
{
int ok=1,i;
while(ok==1)
  {ok=0;
   reset();
   for(i=1;i<=n;i++)
      if(viz[i]==0 && c[i]==0)
         if(dfs(i)==1) ok=1;//cauta drum de crestere;
  }
}

int main()
{   read();
    GenCuplaj();
    solve();
    afisare();
return 0;
}