Cod sursa(job #2698463)

Utilizator ardutgamerAndrei Bancila ardutgamer Data 22 ianuarie 2021 10:40:52
Problema Cuplaj maxim in graf bipartit Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.89 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <climits>
#include <queue>
#include <map>

using namespace std;

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

const int NMAX = 20005;

struct edge {
	int x, y;
};

map<int, int>cap[NMAX];
int p[NMAX], sol[NMAX];

vector<int>g[NMAX];
queue<int>q;

vector<edge> v;

int n, m, e, k, x, y;

void connect()
{
	for (int i = 1; i <= n; i++)
	{
		g[0].push_back(i);
		g[i].push_back(0);
		cap[0][i] = 1;
	}

	for (int i = n+1; i <= k; i++)
	{
		g[i].push_back(k + 1);
		g[k + 1].push_back(i);
		cap[i][k + 1] = 1;
	}

}

void read()
{
	fin >> n >> m >> e;
	k = n + m;
	while (e--)
	{
		fin >> x >> y;
		edge temp;
		temp.x = x;
		temp.y = y;
		v.push_back(temp);
		g[x].push_back(y + n);
		g[y + n].push_back(x);
		cap[x][y + n] = 1;
	}
	connect();
}

int bfs()
{
	while (!q.empty()) q.pop();
	q.push(0);
	while (!q.empty())
	{
		int u = q.front();
		q.pop();
		for (int v : g[u])
		{
			if (cap[u][v] > 0 && !p[v])
			{
				p[v] = u;
				q.push(v);
			}
		}
	}
	return p[k + 1];
}

bool verifEdge(edge &temp)
{
	int x = temp.x;
	int y = temp.y + n;
	return (cap[x][y] == 0);
}

void rebuild()
{
	for (edge temp : v)
		if (verifEdge(temp))
			fout << temp.x << ' ' << temp.y << '\n';
}

int maxFlow()
{
	int flow = 0;
	while (bfs())
	{
		for (int v : g[k + 1])
		{
			int capMin = cap[v][k + 1];
			for (int i = v; p[i] != 0; i = p[i])
				capMin = min(capMin, cap[p[i]][i]);
			for (int i = v; p[i] != 0; i = p[i])
			{
				cap[p[i]][i] -= capMin;
				cap[i][p[i]] += capMin;
			}

			flow += capMin;
			cap[v][k+1] -= capMin;
			cap[k+1][v] += capMin;

		}

		for (int i = 0; i <= k + 1; i++)
			p[i] = 0;

	}

	return flow;
}



int main()
{
	read();
	fout << maxFlow() << '\n';
	rebuild();
	return 0;
}