Cod sursa(job #989131)

Utilizator Cosmin1490Balan Radu Cosmin Cosmin1490 Data 24 august 2013 21:25:24
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.92 kb
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <fstream>
using namespace std;
  
const string file = "cuplaj";
  
const string infile = file + ".in";
const string outfile = file + ".out";

int N, M, E;
vector<vector<int> > G;
vector<int> match;

int totalMatch;

void DFS(queue<int> frees)
{
	vector<int> parent;
	parent.resize(N + M + 1);
	while(frees.empty() == false)
	{
		int current = frees.front();
		frees.pop();
		stack<int> s;
		s.push(current);
		bool done = false;
		while(s.empty() == false)
		{
			
			if(done) break;
			current = s.top();
			s.pop();

			for(vector<int>::iterator itr = G[current].begin();
				itr != G[current].end();
				itr ++)
			{
				if(parent[*itr]) continue;

				if(current <= N && match[*itr] == current)
				{
					parent[*itr] = current;
					s.push(*itr);
				}
				else if(current > N && match[*itr] != current)
				{
					parent[*itr] = current;
					s.push(*itr);
					if(match[*itr] == 0)
					{
						
						int p = parent[*itr];
						int u1 = *itr;
						while(p != 0)
						{
							match[u1] = p;
							match[p] = u1;
							u1 = parent[p];
							p = parent[u1];
						}
						done = true;
						totalMatch ++;
						break;
					}

				}
			}
		}
	}
}

bool BFS()
{
	queue<int> Q;
	queue<int> frees;

	vector<bool> uz;
	uz.resize( N + M + 1);
	for(int i = 1; i <= N; i++)
	{
		if(match[i] == 0)
		{
			Q.push(i);
			uz[i] = true;
		}
	}

	while(Q.empty() == false)
	{
		int current = Q.front();
		Q.pop();

		for(vector<int>::iterator itr = G[current].begin();
			itr != G[current].end();
			itr++)
		{
			if(uz[*itr]) continue;

			if(current <= N && match[*itr] != current)
			{
				if(match[*itr] == 0)
				{
					frees.push(*itr);
				}
				uz[*itr] = true;
				Q.push(*itr);	
			}
			else if(frees.empty() && current > N && match[*itr] == current )
			{
				uz[*itr] = true;
				Q.push(*itr);
			}
		}
	}

	if(frees.empty()) return false;
	DFS(frees);
	return true;
}


int main()
{
	fstream fin(infile.c_str(), ios::in);

	fin >> N >> M >> E;

	G.resize(N + M + 1);
	match.resize( N + M + 1);

	for(int i = 0; i < E; i++)
	{
		int x, y;
		fin >> x >> y;

		G[x].push_back(y + N);
		G[y+N].push_back(x);
	}

	fin.close();

	while(BFS());
	
	fstream fout(outfile.c_str(), ios::out);
	fout << totalMatch << "\n";
	for(int i = 1; i <= N; i++)
	{
		if(match[i] != 0)
		{
			fout << i << " " << match[i] - N << "\n";
		}
	}

	fout.close();
}