Pagini recente » Cod sursa (job #1758655) | Cod sursa (job #1148033) | Cod sursa (job #944143) | Cod sursa (job #2794586) | Cod sursa (job #2963741)
#include <bits/stdc++.h>
#define INF INT_MAX
using namespace std;
ifstream f("cuplaj.in");
ofstream g("cuplaj.out");
//algoritmul lui Hopcroft Karp O(sqrt(VE))
int n, m, e, a, b;
vector<int> v[20001];
queue<int> q;
int d[20001];
int st[20001], dr[20001];
bool BFS() {
//in primul layer de noduri ii setam danta cu 0
for (int i = 1; i <= n; i++)
if (!dr[i]) //daca e liber,il bagam in coada
{
q.push(i);
d[i] = 0;
}
else //notam distanta cu INFinit ca sa fie luat data urmatoare
d[i] = INF;
d[0] = INF; //q o sa aiba nodurile de stanga
while (!q.empty())
{
int nod = q.front();
q.pop();
//daca nodul nu e 0 si poate aduce un short path catre 0
if (d[nod] < d[0])//daca il cuplez pe 0 cu cineva => am gasit cuplaj din lant de lungime minima
{
//parcurgem toti vecinii lui nod
for (auto next: v[nod]) {
if (d[st[next]] == INF)//next e cuplat cu st[next]
{
d[st[next]] = 1 + d[nod];
q.push(st[next]);
}
}
}
}
return d[0] != INF; //lant
// adevarat daca e un augmenting path incepand cu nodul liber nod
}
bool DFS(int nod)
{
if(nod != 0)
{
for(auto next : v[nod])
if(d[nod]+1 == d[st[next]] && DFS(st[next]))
{
st[next] = nod;
dr[nod] = next;
return true;
}
//nu am gasit path
d[nod] = INF;
return false;
}
return true;
}
int matchy()
{
int ans = 0;
while(BFS())
{
for(int i = 1 ; i <= n ; i++)
if(!dr[i] && DFS(i))
ans++;
}
return ans;
}
int main(){
f >> n >> m >> e;
fill(st, st + 20001, 0);
fill(dr, dr + 20001, 0);
for(int i = 1 ; i <= e ; i++)
{
f >> a >> b;
v[a].push_back(b);
}
g << matchy() << '\n';
for(int i = 1 ; i <= m ; i++)
if(st[i])
g << st[i] << ' ' << i << '\n';
return 0;
}
//complexitate algoritm: O(sqrt(VE))
//codul de mai sus este o alta varianta de implementare a codului Ford-Fulkerson
//pentru a gasi cardinalitatea buna intr-un graf bipartit. Alg foloseste
//parcurgerea BFS pentru a gasi drumurile augmentate, iar parcurgerea
//DFS o foloseste pt a gasi drumul augmentat din ultimul vertex, gasit in
//BFS
//in vectorul v stocam nodurile, q e coada pt BFS, d -> distanta pt fiecare
//vertex, st si dr -> stanga si dreapta
// Functia matchy foloseste loopul while care functioneaza atat timp cat
//exista un drum augmentat in graf. In while, incepe un for prin care
//incepe cu un ciclu nevizitat, unmatched si fol DFS pentru a gasi drumul
//augmentat. Daca-l gaseste, il creste pe ans-> variabila care numara
//numarul de drumuri potrivite
//Functia main apeleaza functia matchy si afiseaza ce se cere in cerinta.