Pagini recente » Cod sursa (job #1906511) | Cod sursa (job #2704406) | Cod sursa (job #462322) | Cod sursa (job #579609) | Cod sursa (job #2586077)
#define oo 0x3f3f3f3f
#define NMAX 10005
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
ifstream f("cuplaj.in");
ofstream g("cuplaj.out");
typedef pair<int, int> pii;
int n, m, e, nrM;
int isPairedU[NMAX], isPairedV[NMAX];
vector<int> Gu[NMAX]; // gu[u].push_back(v) - de la u la v
void read()
{
int x, y;
f>>n>>m>>e;
for(int i = 1; i <= e; ++i)
{
f>>x>>y;
Gu[x].push_back(y);
}
}
queue<int> Q;
int dmin[NMAX];
bool bfs()
{
// trebuie pornit drumul minim (dpdv al muchiilor parcurse) ALTERNANT (folosit-nefolosit) din toate nodurile din U neviz
for(int vf = 1; vf <= n; ++vf){
if(isPairedU[vf] == 0)
{
Q.push(vf);
dmin[vf] = 0;
}
else dmin[vf] = oo;
}
dmin[0] = oo;
while(!Q.empty())
{
int top = Q.front();
Q.pop();
if(dmin[top] < dmin[0])
for(auto v:Gu[top])
if(dmin[isPairedV[v]] == oo) // top -> (muchie nefol) v -> (muchie fol) isPairedV[v] (drum altern)
{
dmin[isPairedV[v]] = dmin[top] + 1; // daca v nu a fost 'cuplat' (isPaired=0) se modif dmin[0] => nu caut d mai lungi
Q.push(isPairedV[v]);
}
}
return dmin[0]!=oo; // am gasit un drum
}
bool dfs(int x)
{
if(x == 0)
return 1;
for(auto &y:Gu[x])
if(dmin[isPairedV[y]] == dmin[x]+1 && dfs(isPairedV[y]))
{
isPairedU[x] = y;
isPairedV[y] = x;
return 1;
}
dmin[x] = oo;
return 0;
}
void hopcroft_karp()
{
while(bfs())
{
for(int u = 1; u <= n; ++u) // gaseste un vf nevizitat in U
if(isPairedU[u] == 0 && dfs(u)) // refac M (in dfs)
nrM++; // numarul de muchii din cuplaj
}
}
void write()
{
g<<nrM<<"\n";
for(int u = 1; u <= n; ++u)
if(isPairedU[u])
g<<u<<" "<<isPairedU[u]<<'\n';
}
int main()
{
read();
hopcroft_karp();
write();
return 0;
}