Pagini recente » Cod sursa (job #2426223) | Cod sursa (job #2524456) | Cod sursa (job #1474507) | Cod sursa (job #175463) | Cod sursa (job #2962347)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <climits>
using namespace std;
ifstream fin("cuplaj.in");
ofstream fout("cuplaj.out");
int N, M, E, nr, x, y, sursa, dest;
struct muchie
{
int nod1, nod2, capacitate, poz;
};
vector<muchie> muchii;
//matrice indici--> indicii muchiilor incidente nodului
vector<vector<int>> mIndici;
vector<bool> viz;
vector<int> tata;
void adMuchie(int x, int y)
{
int p = (int)muchii.size();
muchie m;
// adaugam indicii muchiei
mIndici[y].push_back(p + 1);
// adaugam muchia de capacitate 1
m.nod1 = x;
m.nod2 = y;
m.capacitate = 1;
m.poz = p + 1;
muchii.push_back(m);
// repetam pentru inversa
mIndici[x].push_back(p);
// adaugam muchia de capacitate 0
m.nod1 = y;
m.nod2 = x;
m.capacitate = 0;
m.poz = p;
muchii.push_back(m);
}
bool BFS()
{
tata.clear();
tata.resize(nr);
viz.clear();
viz.resize(nr, false);
viz[sursa] = true;
queue<int> q;
q.push(sursa);
while (!q.empty())
{
int nod = q.front();
q.pop();
if (nod != dest)
{
// iteram prin indicii muchiilor incidente
for (int i : mIndici[nod])
{
muchie m = muchii[i];
if (!viz[m.nod2] && m.capacitate != 0) // conditie nod nevizitat&capacitate nedepasita
{
tata[m.nod2] = i; // actualizam tatal
viz[m.nod2] = true;
q.push(m.nod2);
}
}
}
}
return viz[dest]; // false --> flux maxim
}
int FordFulkerson()
{
int maxFlux = 0;
while (BFS()) // cat timp fluxul nu e maxim
{
// parcurgem drumul gasit
for (int i : mIndici[dest])
{
muchie m = muchii[i];
if (viz[m.nod2] && muchii[m.poz].capacitate != 0) // cond nod vizitat si capacitate nedepasita
{
tata[dest] = m.poz;
// determinam val min a muchiilor de pe drumul gasit
int flux = INT_MAX;
for (int nod = dest; nod != sursa; nod = muchii[tata[nod]].nod1)
flux = min(flux, muchii[tata[nod]].capacitate);
// actualizam valorile de pe drum + inversele lor
for (int nod = dest; nod != sursa; nod = muchii[tata[nod]].nod1)
{
muchii[tata[nod]].capacitate -= flux;
muchii[muchii[tata[nod]].poz].capacitate += flux;
}
maxFlux += flux;
}
}
}
return maxFlux;
}
int main()
{
fin >> N >> M >> E;
nr = N + M + 2; // nr total de noduri
// se adauga nod sursa si nod des
sursa = 0, dest = nr - 1;
mIndici.resize(nr);
for (int i = 0; i < E; i++)
{
fin >> x >> y;
adMuchie(x, y + N); // y+N pentru a nu se suprapune pozitiile
}
// adaugam muchii de la nodul sursa la toate celelalte din prima multime
for (int i = 1; i <= N; i++)
adMuchie(sursa, i);
// adaugam muchii de la nodul dest la cele din a doua multime
for (int i = 1; i <= M; i++)
adMuchie(i + N, dest);
fout<<FordFulkerson()<<'\n'; // valoarea cuplajului maxim
for (muchie m : muchii)
if (m.nod1 < m.nod2 && m.nod1 != sursa && m.nod2 != dest && m.capacitate == 0)
fout<<m.nod1<<' '<<m.nod2 - N<<'\n'; // muchiile din cuplaj
return 0;
}