Cod sursa(job #555133)

Utilizator Andreid91Ciocan Andrei Andreid91 Data 15 martie 2011 12:03:21
Problema Cuplaj maxim in graf bipartit Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 2.06 kb
#include<fstream.h>
#include<vector>

using namespace std;

struct nod { int ind, flux,cap; };

vector <nod > v[20005];

int n,m,sw[20005],C[2000000],tata[20005],sol;

int getflux()
{
	int nr,i,sw1,u,p,k;
	vector<nod> :: iterator it,it2;
	
	memset(sw,0,sizeof(sw));
	C[1]=0;sw[0]=sw[m+1]=1;p=u=1;
	tata[0]=-1;
	
	while (p<=u)
	{
		it2=v[C[p]].end();
		for (it=v[C[p]].begin();it<it2;++it)
			if (sw[it->ind]==0 && it->cap>it->flux)
			{
				sw[it->ind]=1;
				C[++u]=it->ind;
				tata[it->ind]=C[p];
			}
		p++;
	}

	nr=0;
	for (i=n+1;i<=m;i++)
		if (sw[i])
		{
			for (it2=v[i].begin();((it2->ind)!=m+1);++it2);
			
			if ((it2->flux)<(it2->cap))
			{
				sw1=1;k=i;
				while (sw1 && (tata[k]>=0))
				{
					for (it=v[tata[k]].begin();it->ind!=k; ++it);
					if ((it->flux)>=(it->cap))
						sw1=0;
					k=tata[k];
				}
				
				if (sw1)
				{
					nr++;
					it2->flux++;
					k=i;
					while (tata[k]>=0)
					{
						for (it=v[tata[k]].begin();it->ind!=k && it<v[tata[k]].end();++it);
						it->flux++;
						for (it=v[k].begin();it->ind!=tata[k] && it<v[k].end();++it);
							if (it<v[k].end()) it->flux=it->flux-1;
						k=tata[k];
					}
				}
			}
		}
	return nr;
}


void  calculate ()
{
	int f=0; 
	do
	{
		f=getflux();
		sol+=f;
	}
	while (f>0) ;
}
void citire()
{
	int i,e,a,b;
	nod val;
	ifstream f("cuplaj.in");
	f>>n>>m>>e;
	m=n+m;
	for (i=1;i<=e;i++)
	{
		f>>a>>b;
		val.ind=b+n;val.flux=0; val.cap=1;
		v[a].push_back(val);
		val.ind=a;val.cap=0;
		v[b+n].push_back(val);
	}
	f.close();
	
	for (i=1;i<=n;i++)
	{
		val.ind=i;val.cap=1; val.flux=0;
		v[0].push_back(val);
	}
	
	for (i=n+1;i<=m;i++)
	{
		val.ind=m+1;val.cap=1;val.flux=0;
		v[i].push_back(val);
	}
}

void afisare ()
{
	int i;
	vector <nod> :: iterator it;
	
	ofstream g("cuplaj.out");
	g<<sol<<'\n';
	for (i=1;i<=n;i++)
		for (it=v[i].begin();it<v[i].end();++it)
			if (it->flux)
				g<<i<<' '<<it->ind-n<<'\n';
	g.close();
}

int main()
{
	citire();
	calculate();
	afisare();
	return 0;
}