Cod sursa(job #750350)

Utilizator vlad.doruIon Vlad-Doru vlad.doru Data 21 mai 2012 21:53:24
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.54 kb
#include <fstream>
#include <vector>
#include <cstring>

#define pb push_back

using namespace std;

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

const int MAX=10010;

vector <int> muchii[MAX];
int st[MAX],dr[MAX],n,m,e; // valoarea lui st[i] inseamna ca nodul i din stanga e cuplat cu nodul st[i] din dreapta
bool viz[MAX];

void citeste(){
	int x,y;
	in>>n>>m>>e;
	while(e--){
		in>>x>>y;
		muchii[x].pb(y);
	}
}

void reset(){
	memset(viz,0,sizeof(viz));
}

bool cupleaza(int x){
	if(viz[x]) // daca am incercat deja sa amelioram prin x intoarcem fals
		return false;
	viz[x]=true;
	int i,vecin;
	for(i=0;i<muchii[x].size();++i){
		vecin=muchii[x][i];
		if(dr[vecin]==0){ // daca avem un vecin care nu e ocupat il cuplam cu nodul x
			dr[vecin]=x;
			st[x]=vecin;
			return true;
		}
	}
	for(i=0;i<muchii[x].size();++i){
		vecin=muchii[x][i];
		if(cupleaza(dr[vecin])){ // incercam sa cuplam x cu fiecare vecin si in acelasi timp sa putem cupla "vecinul vecinului" cu un alt nod
			st[x]=vecin;
			dr[vecin]=x;
			return true;
		}
	}
	return false;
}

void rezolva(){
	int cardinal=0,i;
	bool ok=true;
	while(ok){ // executam cat timp exista drum de ameliorare
		ok=false;
		reset();
		for(i=1;i<=n;++i){
			if(st[i]==0 && cupleaza(i)==true){ // exista drum de ameliorare
				ok=true;
			}
		}
	}
	for(i=1;i<=n;++i){
		if(st[i])
			cardinal++;
	}
	out<<cardinal<<"\n";
	for(i=1;i<=n;++i){
		if(st[i])
			out<<i<<" "<<st[i]<<"\n";
	}
}

int main(){
	citeste();
	rezolva();
	return 0;
}