Pagini recente » Cod sursa (job #1732408) | Cod sursa (job #136556) | Cod sursa (job #710700) | Cod sursa (job #2445060) | Cod sursa (job #418237)
Cod sursa(job #418237)
// Catalin Balan
// Mon Mar 15 17:35:37 EET 2010
// Cuplaj maxim in graf bipartit
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <cstring>
using namespace std;
#define NMAX 10005
#define CHUNK 8192
#define FIN "cuplaj.in"
#define FOUT "cuplaj.out"
char g_buf[CHUNK];
int g_p=CHUNK-1;
inline int get()
{
int x = 0;
while (g_buf[g_p] < '0' || g_buf[g_p] > '9')
if (++g_p == CHUNK) fread(g_buf,1,CHUNK,stdin), g_p=0;
while (g_buf[g_p] >= '0' && g_buf[g_p] <= '9')
{
x = x*10 + g_buf[g_p]-'0';
if (++g_p == CHUNK) fread(g_buf,1,CHUNK,stdin), g_p=0;
}
return x;
}
int n,m;
int Right[NMAX], Left[NMAX], Viz[NMAX];
vector<int> G[NMAX];
// Right[i] - vecinul nodului i; i se afla in multimea din dreapta
// Left[i] - vecinul nodului i; i se afla in multimea din stanga
int group( int st )
{
if (Viz[st]) return false;
Viz[st] = true;
vector<int>::iterator it;
for (it = G[st].begin(); it != G[st].end(); ++it)
{
if (!Right[*it])
{
Left[st] = *it;
Right[*it] = st;
return true;
}
}
for (it = G[st].begin(); it != G[st].end(); ++it)
{
if (group (Right[*it]) )
{
Left[st] = *it;
Right[*it] = st;
return true;
}
}
return false;
}
int main(int argv, char ** argc)
{
freopen(FIN, "r", stdin);
freopen(FOUT, "w", stdout);
n = get();
m = get();
for ( int nrMuchii = get(); nrMuchii; --nrMuchii)
{
int x = get();
int y = get();
G[x].push_back(y);
}
int goOn = true;
while (goOn)
{
goOn = false;
memset(Viz, 0, sizeof(Viz));
for (int i = 1; i <= n; ++i)
if ( !Left[i] ) goOn |= group( i );
}
int cate = 0;
for (int i = 1; i <= n; ++i)
cate += (Left[i] != 0);
printf("%d\n", cate);
for (int i = 1; i <= n; ++i)
if (Left[i])
{
printf("%d %d\n", i, Left[i]);
}
return EXIT_SUCCESS;
}