Cod sursa(job #386964)

Utilizator loginLogin Iustin Anca login Data 26 ianuarie 2010 14:12:35
Problema Cuplaj maxim in graf bipartit Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 1.94 kb
# include <fstream>
# include <iostream>
# define INFINIT 1000000000
using namespace std;
struct nod {
	int capat, cap;
	nod *next;};
int n, m, nv, v[20000], t[20000], cuplaj;
nod *a[20003];

void add_m (int x, int y, int c)
{
	nod *t;
	t=new nod;
	t->capat=y;
	t->cap=c;
	t->next=a[x];
	a[x]=t;
}

void read ()
{
	int e;		
	ifstream fin ("cuplaj.in");
	fin>>n>>m>>e;
	for (int i=1;i<=e;i++)
	{
		int x, y;
		fin>>x>>y;
		add_m(x, n+y, 1);
		add_m(n+y, x, 0);
	}
	for (int i=1;i<=n;i++)
	{
		add_m(0, i, 1);
		add_m(i, 0, 0);
	}
	for (int i=n+1;i<=n+m;i++)
	{
		add_m(i, n+m+1, 1);
		add_m(n+m+1, i, 0);
	}
		
}

int bfs (int s, int d)
{
	int c[20002], st, dr, k;
	st=dr=1;
	for (int i=0;i<=n+m+1;i++)
		t[i]=-2;
	c[st]=s;
	t[s]=-1;
	while (st<=dr)
	{
		k=c[st++];
		for (nod *p=a[k];p;p=p->next)
			if (t[p->capat]==-2 && p->cap)
			{
				c[++dr]=p->capat;
				t[p->capat]=k;
			}
		if (k==d)
		{
		
			return 1;
		}
	}
	return 0;
}

nod *m_adress (int i, int j)
{
	for (nod *p=a[i];p;p=p->next)
		if (p->capat==j)
			return p;
	return NULL;
}

void EK ()
{
	int k, dcur, i, j;
	nod *p;
	while (bfs(0, n+m+1))
		for (j=n+1;j<=n+m;j++)
		{
			p=m_adress (j, m+n+1);
			if (p && p->cap==1 && t[j]!=-2)
			{
				t[n+m+1]=j;
				k=n+m+1;
				dcur=6;
				while ((i=t[k])!=-1)
				{
					p=m_adress(i, k);
					if (p->cap<dcur)
						dcur=p->cap;
					k=i;
				}
				cuplaj+=dcur;
				k=m+n+1;
				while ((i=t[k])!=-1)
				{
					p=m_adress(i, k);
					p->cap-=dcur;
					p=m_adress(k, i);
					p->cap+=dcur;
					k=i;
				}
			}
		}
}			

void afis ()
{
	ofstream fout ("cuplaj.out");
	int gasit;
	fout<<cuplaj<<endl;
	nod *p;
	for (int i=1;i<=n;i++)
		for (p=a[i], gasit=0;p && !gasit;p=p->next)
			if (p->capat>n && p->cap==0)
				fout<<i<<" "<<p->capat-n<<endl, gasit=1;
}

	
int main ()
{
	read ();
	EK ();
	ofstream fout ("f.out");
	afis ();
	return 0;
}