Cod sursa(job #519517)

Utilizator gabipurcaruGabi Purcaru gabipurcaru Data 5 ianuarie 2011 21:12:43
Problema Cuplaj maxim in graf bipartit Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.62 kb
// infoarena: problema/cuplaj //
#include <fstream>
#include <vector>
#include <queue>
#include <set>
using namespace std;

const int MAXN = 20010;
const int MAXM = 20010;

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

vector<int> g[MAXN], vn;
deque<int> q;
vector<int>::iterator it;
set<pair<int,int> > sol;
int n,m,e,i,j,c[MAXN][MAXN],f[MAXN][MAXN],t[MAXN],nod,x,y,z,flux,r,k;

int bfs()
{
	int ret = false;
	for(i=0; i<=n+m+1; i++)
		t[i] = -1;
	
	q.clear();
	q.push_front(0);
	while(!q.empty())
	{
		nod = q.front();
		q.pop_front();
		
		for(it=g[nod].begin(); it!=g[nod].end(); it++)
			if(f[nod][*it] < c[nod][*it] && t[*it]==-1)
			{
				if(*it == n+m+1)
					ret = true;
				t[*it] = nod;
				q.push_back(*it);
			}
	}
	return ret;
}

int main()
{
	in>>n>>m>>e;
	for(i=1; i<=e; i++)
	{
		in>>x>>y;
		g[x].push_back(y+n);
		g[y+n].push_back(x);
		c[x][y+n] = 1;
		c[0][x] = 1;
		c[y+n][n+m+1] = 1;
		vn.push_back(y+n);
	}
	for(i=1; i<=n+m; i++)
		if(i<=n)
			g[0].push_back(i);
		else
			g[i].push_back(n+m+1);
	
	while(bfs())
	{
		for(it=vn.begin(); it!=vn.end(); it++)
		{
			if(t[*it] <= 0)
				continue;
			i = *it;
			r = c[i][n+m+1] - f[i][n+m+1];
			if(r<=0)
				continue;
			while(i!=0)
			{
				r = min(r, c[t[i]][i] - f[t[i]][i]);
				i = t[i];
			}
			
			i = *it;
			f[*it][n+m+1] += r;
			f[n+m+1][*it] -= r;
			while(i!=0)
			{
				f[t[i]][i] += r;
				f[i][t[i]] -= r;
				k = t[i];
				i = k;
			}
			flux += r;
		}
	}
	out<<flux<<'\n';
    for(i=1; i<=n; i++)
        for(j=1; j<=m; j++)
            if(f[i][j+n] == 1)
            {
                out<<i<<' '<<j<<'\n';
                break;
            }

	return 0;
}