Cod sursa(job #2985718)

Utilizator TudosieRazvanTudosie Marius-Razvan TudosieRazvan Data 26 februarie 2023 21:56:07
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.19 kb
#include <cstdio>
#include <cmath>
#include <climits>
#include <vector>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <bitset>
#include <unordered_map>
#include <cstring>
#include <algorithm>

#define NMAX 10003

using namespace std;


FILE* fin, * fout;

int n, m, k;
int solutieMuchii = 0;
bool vizitat[NMAX];
int st[NMAX], dr[NMAX];//st[i] am conexiune la stanga pentru nodul i, respectiv am conexiune la dr pentru nodul i
//OBS. st[i] inseamna ca nodul i se afla in multimea din stanga, si invers pentru dr[i]
vector<int>graf[NMAX];

bool cupleaza(int nod)
{
	if (vizitat[nod])
	{
		//am vizitat deja nodul asta si am facut shiftuirea muchiilor ca sa gasesc maximul
		return false;
	}
	vizitat[nod] = true;
	//incerc sa il cuplez la un nod care nu a mai fost cuplat
	for (int i = 0; i < graf[nod].size(); i++)
	{
		int vecin = graf[nod][i];
		if (dr[vecin] == 0)
		{
			//pot cupla cele doua noduri
			solutieMuchii++;
			st[nod] = vecin;
			dr[vecin] = nod;
			return true;
		}
	}
	//poate gasesc o varianta sa mut celelalte muchii ca sa am cuplaj
	for (int i = 0; i < graf[nod].size(); i++)
	{
		int vecin = graf[nod][i];
		if (cupleaza(dr[vecin]))
		{
			//pot cupla cele doua noduri
			st[nod] = vecin;
			dr[vecin] = nod;
			return true;
		}
	}
	return false;
}

int main()
{
	fin = fopen("cuplaj.in", "r");
	fout = fopen("cuplaj.out", "w");


	fscanf(fin, "%d %d %d", &n, &m, &k);
	for (int i = 1; i <= k; i++)
	{
		int x, y;
		fscanf(fin, "%d %d", &x, &y);
		graf[x].push_back(y);//imi iau graful ca si cum ar fi orientat ca sa lucrez doar cu o singura multime de noduri
	}

	bool ok = false;//daca pot crea conexiune noua
	do {
		//resetez nebuniile
		ok = false;
		memset(vizitat, 0, sizeof(vizitat));
		//parcurg toate nodurile sa vad daca se produce o schimbare
		for (int i = 1; i <= n; i++) {
			if (st[i] == 0 && cupleaza(i) == 1)
			{
				ok = true;
			}
		}
	} while (ok == true);

	fprintf(fout, "%d\n", solutieMuchii);
	for (int i = 1; i <= n; i++) {
		if (st[i] != 0)
		{
			fprintf(fout, "%d %d\n", i, st[i]);//afisez cuplajul(puteam sa afisez si i si dr[i] daca dr[i]!=0)
		}
	}
	return 0;
}