Cod sursa(job #709223)

Utilizator rusu_raduRusu Radu rusu_radu Data 7 martie 2012 20:38:01
Problema Cuplaj maxim in graf bipartit Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.17 kb
#include <cstdio>
#include <cassert>
#include <vector>
#include <queue>
#include <algorithm>
#define Nmax 10005
#define INF (int)1e9
#define InFile "cuplaj.in"
#define OutFile "cuplaj.out"
#define pb push_back

using namespace std;

int n, m, e, srs, dst;
int viz[Nmax], pz[Nmax], loc[Nmax], T[Nmax], pzd[Nmax];
vector <int> A[Nmax], C[Nmax], F[Nmax];

void read();
void graph();
void solve();
int BFS();
inline int Abs (int x) {if (x>0) return x; return -x;}
void write();

int main()
{
  assert (freopen (InFile, "r", stdin));
  assert (freopen (OutFile, "w", stdout));
  read();
  graph();
  solve();
  write();
  return 0;
}

void read()
{
  int i, x, y;
  scanf ("%d %d %d\n", &n, &m, &e);
  for (i=1; i<=e; i++)
  {
    scanf ("%d %d\n", &x, &y); y+=n;
    loc[x]=1; loc[y]=2;
    A[x].pb (y); C[x].pb(1); F[x].pb(0);
    A[y].pb (x); C[y].pb(0); F[y].pb(0);
  }
  n+=m;
  m=n-m;
}

void graph()
{
  int i;
  srs=n+1; dst=n+2;
  n+=2;
  for (i=1; i<=n-2; i++)
    if (loc[i]==1)
    {
      A[srs].pb(i); C[srs].pb(1); F[srs].pb(0);
      A[i].pb(srs); C[i].pb(0); F[i].pb(0);
    }
    else
    {
      A[i].pb (dst); C[i].pb(1); F[i].pb(0);
      pzd[i]=A[i].size()-1;
      A[dst].pb(i); C[dst].pb(0); F[dst].pb(0);
    }
}

void solve()
{
  int i, j, x, nd, poz, lg, flux, cap, a, b, v, q;
  while (BFS())
  {
    lg=A[dst].size();
    for (j=0; j<lg; j++)
    {
      x=A[dst][j]; cap=C[x][pzd[x]]; flux=F[x][pzd[x]];
      if (viz[x] && flux<cap)
      {
        q=0; T[q]=dst;
        a=b=INF;
        if (flux<cap)
          viz[dst]=x, pz[dst]=pzd[x];
        while (T[q]!=srs)
        {
          q++;
          nd=Abs (viz[T[q-1]]);
          poz=pz[T[q-1]];
          T[q]=nd;
          if (viz[nd]>0)
            a=min (a, C[nd][poz]-F[nd][poz]);
          else
            if (viz[nd]<0)
              b=min (b, F[nd][poz]);
        }
        v=min (a, b);
        for (i=q; i>0 && v; i--)
        {
          poz=pz[T[i-1]];
          if (viz[T[i-1]]>0)
            F[T[i]][poz]+=v;
          else
            if (viz[T[i-1]]<0)
              F[T[i]][poz]-=v;
        }
      }
    }
  }
}

int BFS ()
{
  int i, x, y, lg, flux, cap;
  queue <int> Q;
  for (i=1; i<=n; i++) viz[i]=0;
  Q.push (srs); viz[srs]=srs; pz[srs]=0;
  while (!Q.empty())
  {
    x=Q.front(); Q.pop();
    lg=A[x].size();
    for (i=0; i<lg; i++)
    {
      y=A[x][i]; cap=C[x][i]; flux=F[x][i];
      if (!viz[y])
        if (cap>flux && cap)
        {
          viz[y]=x;
          pz[y]=i;
          if (y!=dst) Q.push(y);
        }
        else
          if (flux>0 && !cap)
          {
            viz[y]=-x;
            pz[y]=i;
            if (y!=dst) Q.push (y);
          }
    }
  }
  return viz[dst];
}

void write()
{
  int i, j, sum=0, q=0, lg;
  struct Mc {int x, y;} M[Nmax];
  for (i=1; i<=n-2; i++)
  {
    lg=A[i].size();
    for (j=0; j<lg; j++)
    {
      if (A[i][j]==dst)
        sum+=F[i][j];
      if (F[i][j]==1 && i<=m)
        M[q].x=i, M[q++].y=A[i][j];
    }
  }
  printf ("%d\n", sum);
  for (i=0; i<q; i++)
    printf ("%d %d\n", M[i].x, M[i].y-m);
}