Pagini recente » Cod sursa (job #577860) | Cod sursa (job #2990849) | Cod sursa (job #3161391) | Cod sursa (job #1736665) | Cod sursa (job #2956474)
#include <bits/stdc++.h>
#define inf INT_MAX
using namespace std;
ifstream f("cuplaj.in");
ofstream g("cuplaj.out");
int n, m, e, a, b;
vector<int> la[20001];
queue<int> q;
int dist[20001];
int stanga[20001], dreapta[20001];
bool bfs() {
//primul layer de nod uri ii setam distanta cu 0
for (int i = 1; i <= n; i++)
if (!dreapta[i]) {
//daca e liber,il bagam in coada
q.push(i);
dist[i] = 0;
}
else//notam distanta cu infinit ca sa fie luat data urmatoare
dist[i] = inf;
dist[0] = inf;
//q o sa aiba nodurile de stanga
while (!q.empty()) {
int node = q.front();
q.pop();
//daca nodul nu e 0 si poate aduce un short path catre 0
if (dist[node] < dist[0])//daca il cuplez pe 0 cu cineva => am gasit cuplaj din lant de lungime minimia
{
//parcurgem toti vecinii lui node
for (auto next: la[node]) {
if (dist[stanga[next]] == inf)//next e cuplat cu stanga[next]
{
dist[stanga[next]] = 1 + dist[node];
q.push(stanga[next]);
}
}
}
}
return dist[0] != inf; //lant
}
//returneaza adevarat daca e un augmenting path incepand cu nodul liber node
bool dfs(int node)
{
if(node != 0)
{
for(auto next : la[node])
if(1 + dist[node] == dist[stanga[next]] && dfs(stanga[next]))
{
stanga[next] = node;
dreapta[node] = next;
return true;
}
//nu am gasit path
dist[node] = inf;
return false;
}
return true;
}
int maxmatch()
{
int ans = 0;
while(bfs())
{
for(int i = 1 ; i <= n ; i++)
if(!dreapta[i] && dfs(i))
ans++;
}
return ans;
}
int main(){
f >> n >> m >> e;
fill(stanga, stanga + 20001, 0);
fill(dreapta, dreapta + 20001, 0);
for(int i = 1 ; i <= e ; i++)
{
f >> a >> b;
la[a].push_back(b);
}
g << maxmatch() << '\n';
for(int i = 1 ; i <= m ; i++)
if(stanga[i])
g << stanga[i] << ' ' << i << '\n';
return 0;
}
//algoritmul lui Hopcroft Karp O(sqrt(VE))