Cod sursa(job #303245)

Utilizator SleepyOverlordPatcas Csaba SleepyOverlord Data 9 aprilie 2009 17:56:47
Problema Cuplaj maxim in graf bipartit Scor 80
Compilator cpp Status done
Runda Arhiva educationala Marime 1.89 kb
//Code by Patcas Csaba
//Time complexity: O(n*m)
//Space complexity: O(n+m)
//Method: Drumuri alternante
//Working time: 25 minutes

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

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;
vector <bool> was;

bool df(int node, int father)
{
	was[node]=true;
	if (node>n1 && !match[node])
	{
		match[node]=father;
		match[father]=node;
		return true;
	}
	if (node<=n1)
	{
		FORN(i,g[node].S)
			if (!match[g[node][i]])
			{
				df(g[node][i],node);
				match[node]=g[node][i];
				match[g[node][i]]=node;
				return true;
			}
		FORN(i,g[node].S)
		if (!was[g[node][i]] && match[node]!=g[node][i])
		{
			bool aux=df(g[node][i],node);
			if (aux) 
			{
				match[node]=g[node][i];
				match[g[node][i]]=node;
				return true;
			}
		}
	}
	else 
	{
		bool aux=df(match[node],node);
		if (aux) return true;
	}
	return false;
}

void solve()
{
	match.resize(n1+n2+1);
	was.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]) 
			if (df(i,0)) ++solution;
			else
			{
				fill(ALL(was),false);
				solution+=df(i,0);
			}
}

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;
}