Cod sursa(job #303255)

Utilizator SleepyOverlordPatcas Csaba SleepyOverlord Data 9 aprilie 2009 18:02:15
Problema Cuplaj maxim in graf bipartit Scor 24
Compilator cpp Status done
Runda Arhiva educationala Marime 2.04 kb
//Code by Patcas Csaba
//Time complexity: O(n*m)
//Space complexity: O(n+m)
//Method: Drumuri alternante cu BF
//Working time: 10 minutes

#include <stdio.h>
#include <vector>
#include <queue>

using namespace std;

#define in_file "cuplaj.in"
#define out_file "cuplaj.out"

#define VI vector <int> 
#define PB push_back
#define FORN(i,n) for (int i=0;i<n;++i)
#define FOR(i,a,b) for (int i=a;i<=b;++i)
#define ALL(x) x.begin(),x.end()
#define S size()

int n1,n2,m,solution;
vector <VI> g;
VI match, father;

int bf(int node)
{
	queue<int> l;
	l.push(node);
	father[node]=-1;
	while (!l.empty())
	{
		int aux=l.front();
		if (aux<=n1)
			FORN(i,g[aux].S)
			if (!father[g[aux][i]])
			{
				father[g[aux][i]]=aux;
				if (!match[g[aux][i]]) return g[aux][i];
				l.push(g[aux][i]);
			}
			else;
		else
		{
			father[match[aux]]=aux;
			l.push(match[aux]);
		}
		l.pop();
	}
	return 0;
}

void ChangePath(int node)
{
	bool color=true;
	while (father[node]>0)
	{
		if (color)
		{
			match[node]=father[node];
			match[father[node]]=node;
		}
		color=!color;
		node=father[node];
	}
}

void solve()
{
	match.resize(n1+n2+1);
	father.resize(n1+n2+1);
	solution=0;
	FOR(i,1,n1)
		FORN(j,g[i].S)
		if (!match[g[i][j]])
		{
			match[i]=g[i][j];
			match[g[i][j]]=i;
			++solution;
			break;
		}
		FOR(i,1,n1)
			if (!match[i]) 
			{
				int aux=bf(i);
				if (aux)
				{
					fill(ALL(father),0);
					ChangePath(aux);
					++solution;
				}
				/*else
				{
					fill(ALL(father),0);
					int aux2=bf(i);
					if (aux2)
					{
						ChangePath(aux);
						++solution;
					}
				}*/
			}
}

int main()
{
	FILE* fin=fopen(in_file,"r");
	fscanf(fin,"%d%d%d",&n1,&n2,&m);
	g.resize(n1+n2+1);
	FORN(q,m)
	{
		int x,y;
		fscanf(fin,"%d%d",&x,&y);
		g[x].PB(y+n1);
		g[y+n1].PB(x);
	}
	fclose(fin);

	solve();

	FILE* fout=fopen(out_file,"w");
	fprintf(fout,"%d\n",solution);
	FOR(i,1,n1)
		if (match[i]) fprintf(fout,"%d %d\n",i,match[i]-n1);
	fclose(fout);

	return 0;
}