Cod sursa(job #2590509)

Utilizator MarcGrecMarc Grec MarcGrec Data 28 martie 2020 10:09:55
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.77 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);
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, PrimVec(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;
}
	
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);
			}
		}
	}
}