Cod sursa(job #2590585)

Utilizator MarcGrecMarc Grec MarcGrec Data 28 martie 2020 14:21:14
Problema Cuplaj maxim in graf bipartit Scor 64
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.64 kb
#define MAX_NM 10000

#include <fstream>
#include <vector>
#include <queue>
#include <utility>
#include <algorithm>
using namespace std;

ifstream fin("cuplaj.in");
ofstream fout("cuplaj.out");

int n, m, e, D[(MAX_NM * 2) + 1];
vector<int> G[(MAX_NM * 2) + 1];
queue<int> Term;

vector<pair<int, int>> Rasp;

void Init();
int PrimVec(int nod);
int Estimeaza(int nod1, int nod2);
void Cupleaza(int nod);
void Cupleaza(int nod1, int nod2);

int main()
{
	fin >> n >> m >> e;
	for (int i = 0, u, v; i < e; ++i)
	{
		fin >> u >> v;
		v += n;
		
		G[u].push_back(v);
		++D[u];
		
		G[v].push_back(u);
		++D[v];
	}
	
	Init();
	
	int nodL = 0;
	bool ok;
	do
	{
	INCEPUT:
		while (!Term.empty())
		{
			int nod = Term.front();
			Term.pop();
			
			if (D[nod] == 1)
			{
				Cupleaza(nod, PrimVec(nod));
			}
		}
		
		ok = false;
		while ((++nodL) <= n)
		{
			if (D[nodL] != 0)
			{
				Cupleaza(nodL);
				if (!Term.empty())
				{
					goto INCEPUT;
				}
				ok = true;
			}
		}
	}
	while(ok);
	
	fout << Rasp.size() << '\n';
	for (size_t i = 0; i < Rasp.size(); ++i)
	{
		fout << Rasp[i].first << ' ' << Rasp[i].second << '\n';
	}
	
	fin.close();
	fout.close();
	return 0;
}

void Init()
{
	for (int i = 1; i <= (n + m); ++i)
	{
		if (D[i] == 1)
		{
			Term.push(i);
		}
	}	
}

int PrimVec(int nod)
{
	for (int vecin : G[nod])
	{
		if (D[vecin] != 0)
		{
			return vecin;
		}
	}
	
	return -1;
}

int V[(2 * MAX_NM) + 1];
int Estimeaza(int nod1, int nod2)
{
	for (int nod : { nod1, nod2 })
	{
		for (int vecin : G[nod])
		{
			if ((vecin != nod1) && (vecin != nod2))
			{
				if (D[vecin] == 2)
				{
					for (int vecinSq : G[vecin])
					{
						if ((vecinSq != vecin) && (D[vecinSq] != 0))
						{
							++V[vecinSq];
							break;
						}
					}
				}
			}
		}
	}
	
	int res = 0;
	for (int i = 1; i <= (n + m); ++i)
	{
		if (V[i] != 0)
		{
			res += V[i] - 1;
			V[i] = 0;
		}
	}
	
	return res;
}

void Cupleaza(int nod)
{
	int mi     = 2 * MAX_NM;
	int nodAux = -1;
	for (int vecin : G[nod])
	{
		int aux = Estimeaza(nod, vecin);
		if (mi > aux)
		{
			mi     = aux;
			nodAux = vecin;
		}
		
		if (mi == 0) { break; }
	}
	
	if (nodAux != -1)
	{
		Cupleaza(nod, nodAux);
	}
}

void Cupleaza(int nod1, int nod2)
{
	{
		int nodL = (nod2 > n) ? nod1 : nod2;
		int nodR = (nod1 > n) ? nod1 : nod2;
	
		Rasp.emplace_back(nodL, nodR - n);
	}
	
	D[nod1] = D[nod2] = 0;
	for (int nod : { nod1, nod2 })
	{
		for (int vecin : G[nod])
		{
			if ((D[vecin] != 0) && ((--D[vecin]) == 1))
			{
				Term.push(vecin);
			}
		}
	}
}