Pagini recente » Cod sursa (job #3130515) | Cod sursa (job #2100747) | Cod sursa (job #2731669) | Cod sursa (job #222624) | Cod sursa (job #2960594)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>
#include <string>
using namespace std;
ifstream f("cuplaj.in");
ofstream g("cuplaj.out");
vector<int> vizitat;
vector<int> tata;
vector<vector<int>> indice_muchii; //aici vom retine indicii acelor muchii din vectorul de muchii, al caror capat este nodul i
struct muchie
{
int x, y, capacitate, poz; // ne ajuta aceasta structura sa retinem strict muchiile care sunt in graf
//in schimb, daca faceam o matrice de capacitati de dimensiune n*m, atunci ar fi fost nevoie sa retinem si muchiile care nu sunt in graf
//si depaseam memoria disponibila
};
vector<muchie> muchii;
int n, m, sursa, dest, l, r;
int bfs(){
tata.clear();
tata.resize(n);
fill(vizitat.begin(), vizitat.end(), 0);
queue<int> coada;
coada.push(sursa);
vizitat[sursa] = 1;
while(!coada.empty()){
int nod = coada.front();
coada.pop();
if(nod == dest)
continue;
for(int i : indice_muchii[nod]){
muchie m_curent = muchii[i];
if(!vizitat[m_curent.y] and m_curent.capacitate != 0){
vizitat[m_curent.y] = 1;
tata[m_curent.y] = i; //retinem muchia care ne duce la nodul m.y
coada.push(m_curent.y);
}
}
}
return vizitat[dest];
}
int fluxMaxim(){
int maxFlux = 0;
//facem bfs cat timp mai exista drumuri de la sursa la destinatie pe care sa le verificam pentru fluxul maxim
//in cazul in care nu mai exista drumuri, atunci nu mai avem ce sa mai cautam
while(bfs()){
for(auto i:indice_muchii[dest]){
if(vizitat[muchii[i].y] and muchii[muchii[i].poz].capacitate != 0){
//daca am gasit o muchie care duce la destinatie si care are capacitatea diferita de 0
//atunci vom cauta drumul de la sursa la destinatie pe care il vom folosi pentru a afla fluxul maxim
int flux = 1e9;
muchie m_curent = muchii[i];
tata[dest] = m_curent.poz;
int nod = dest;
while(nod != sursa){
flux = min(flux, muchii[tata[nod]].capacitate);
nod = muchii[tata[nod]].x;
}
nod = dest;
while(nod != sursa){
//actualizam capacitatea muchiilor
muchii[tata[nod]].capacitate -= flux;
muchii[muchii[tata[nod]].poz].capacitate += flux;
nod = muchii[tata[nod]].x;
}
//actualizam fluxul maxim
maxFlux += flux;
}
}
}
return maxFlux;
}
int main() {
f>>l>>r>>m;
n = l + r + 2;
sursa = 0;
dest = n - 1;
vizitat.resize(n);
tata.resize(n); //tata[i] = nodul din care am ajuns in nodul i
indice_muchii.resize(n); //indice_muchii[i] = vectorul de indici ai muchiilor care pleaca din nodul i
for(int i = 1; i <= m; i++){
int x, y;
f>>x>>y;
muchii.push_back({x, y + l, 1, 2 * i - 1});
muchii.push_back({y + l, x, 0, 2 * i - 2});
indice_muchii[y + l].push_back(2 * i - 1);
indice_muchii[x].push_back(2 * i - 2);
}
//adaugam un nod sursa care va fi nodul 0 si un nod destinatie care va fi nodul n - 1
//facem muchii de la sursa la fiecare nod din stanga si de la fiecare nod din dreapta la destinatie
//capacitatea maxima a acestor muchii va fi 1
//reducem problema determinarii unui cuplaj maxim intr un graf bipartit la problema
//determinarii unui flux maxim intr-o retea de transport asociata acelui graf bipartit si cu adaugarea
//nodurilor sursa si destinatie
int dimensiune_muchii = int (muchii.size());
for(int i = 1; i <= l; i++){
//adaugam muchii de la sursa la nodurile din stanga
dimensiune_muchii += 2;
muchii.push_back({sursa, i, 1, dimensiune_muchii - 1});
indice_muchii[i].push_back(dimensiune_muchii - 1);
muchii.push_back({i, sursa, 0, dimensiune_muchii - 2});
indice_muchii[sursa].push_back(dimensiune_muchii - 2);
}
for(int i = l + 1; i < n - 1; i++){
//adaugam muchii de la nodurile din dreapta la destinatie
dimensiune_muchii += 2;
muchii.push_back({i, dest, 1, dimensiune_muchii - 1});
indice_muchii[dest].push_back(dimensiune_muchii - 1);
muchii.push_back({dest, i, 0, dimensiune_muchii - 2});
indice_muchii[i].push_back(dimensiune_muchii - 2);
}
// //afisare muchii
// for(muchie m : muchii){
// cout<<m.x<<" "<<m.y<<" "<<m.capacitate<<" "<<m.poz<<endl;
// }
//
// //afisare indice_muchii
// for(int i = 0; i < indice_muchii.size(); i++){
// cout<<i<<": ";
// for(int j : indice_muchii[i]){
// cout<<j<<" ";
// }
// cout<<endl;
// }
g<<fluxMaxim()<<"\n";
//nodurile cuplate vor reprezenta arcele care fac parte din cuplajul maxim si au capacitatea 0 in matricea de capacitate
//si care nu sunt adiacente cu nodul sursa sau destinatie
for(auto & i : muchii){
if(i.capacitate == 0 and i.x != sursa and i.y != dest and i.x < i.y){
g<<i.x<<" "<<i.y - l<<"\n";
}
}
return 0;
}