Pagini recente » Cod sursa (job #469657) | Cod sursa (job #350175) | Cod sursa (job #1400027) | Cod sursa (job #2403644) | Cod sursa (job #2599909)
#include <fstream>
#include <vector>
#include <queue>
#define NMAX 10005
#define oo 0x3f3f3f3f
using namespace std;
ifstream f("cuplaj.in");
ofstream g("cuplaj.out");
int n, m, e;
vector<int>graph[NMAX];
int isPairedU[NMAX], isPairedV[NMAX];
int dmin[NMAX];
int nrm=0;
void citire(){
f>>n>>m>>e;
int x, y;
for(int i=1; i<=e; i++){
f>>x>>y;
graph[x].push_back(y);
}
}
int bfs(){
queue<int> Q; // in Q voi pune nodurile nevizitate din U
for(int i=1; i<=n; i++){
if(isPairedU[i] == 0){ // daca nodul meu i nu este cuplat cu niciun nod din U
Q.push(i);
dmin[i] = 0;
}
else dmin[i] = oo;
}
dmin[0] = oo;
while(!Q.empty()){
int top = Q.front();
Q.pop();
if(dmin[top]<dmin[0]){
for(auto v:graph[top]) // vecinul lui top din U
if(dmin[isPairedV[v]] == oo){ // daca vecinul din V al vecinului lui top este in matching sdt, asta inseamna ca ne aflam pe o muchie din match
dmin[isPairedV[v]] = dmin[top] + 1;
Q.push(isPairedV[v]);
}
}
}
return dmin[0]!=oo;
}
int dfs(int x){
if(x==0) // asta inseamna ca nodul x face parte din drumul catre un nod nevizitat din U
return 1;
for(auto v:graph[x])
if(dmin[isPairedV[v]] == dmin[x] + 1 && dfs(isPairedV[v])){ // daca drumul x - v - isPairedV[v] a fost parcurs de bfs si ajunge la un nod nevizitat din u
isPairedU[x] = v;
isPairedV[v] = x;
return 1;
}
dmin[x] = oo;
return 0;
}
void HopcroftKarp(){
while(bfs()){
for(int i=1; i<=n; i++){
if(isPairedU[i] == 0 && dfs(i))
nrm++;
}
}
}
void afisare(){
g<<nrm<<'\n';
for(int i=1; i<=n; i++)
if(isPairedU[i] != 0){
g<<i<<" "<<isPairedU[i]<<'\n';
}
}
int main(){
citire();
HopcroftKarp();
afisare();
return 1;
}