Cod sursa(job #2591959)

Utilizator MarcGrecMarc Grec MarcGrec Data 31 martie 2020 18:53:23
Problema Cuplaj maxim in graf bipartit Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.37 kb
#define MAX_NM 10000
#define INF 0x3f3f3f3f

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

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

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

void Cupleaza();
void CupleazaTerminale();
void CupleazaNoduri(int nod1, int nod2);
int Simuleaza(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];
	}
	
	for (int i = 1; i <= (n + m); ++i)
	{
		if (D[i] == 1)
		{
			T.push(i);
		}
	}
	
	Cupleaza();
	
	fout << R.size() << '\n';
	for (size_t i = 0; i < R.size(); ++i)
	{
		fout << R[i].first << ' ' << R[i].second << '\n';
	}
	
	fin.close();
	fout.close();
	return 0;
}

void Cupleaza()
{
	CupleazaTerminale();
	
	int nod = 0;
	while ((++nod) <= (n + m))
	{
		if (D[nod] != 0)
		{
			int mi = INF, nodAux = -1;
			for (int vecin : G[nod])
			{
				if (D[vecin] != 0)
				{
					int res = Simuleaza(nod, vecin);
					if (mi > res)
					{
						mi = res;
						nodAux = vecin;
					}
				}
			}
			
			CupleazaNoduri(nod, nodAux);
			CupleazaTerminale();
		}
	}
}

void CupleazaTerminale()
{
	while (!T.empty())
	{
		int nod = T.front();
		T.pop();
		
		if (D[nod] != 0)
		{
			for (int vecin : G[nod])
			{
				if (D[vecin] != 0)
				{
					CupleazaNoduri(nod, vecin);
					break;
				}
			}
		}
	}
}

void CupleazaNoduri(int nod1, int nod2)
{
	{
		int nodL = (nod1 > n) ? nod2 : nod1;
		int nodR = (nod1 > n) ? nod1 : nod2;
		R.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];
			}
		}
	}
}

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