Pagini recente » Cod sursa (job #223648) | Cod sursa (job #1868781) | Cod sursa (job #2809611) | Cod sursa (job #327600) | Cod sursa (job #2960534)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>
#include <string>
using namespace std;
ifstream f("cuplaj.in");
ofstream g("cuplaj.out");
vector<vector<int>> graf;
vector<int> vizitat;
vector<int> tata;
vector<vector<int>> capacitate;
int n, m, sursa, dest, l, r;
bool 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(auto &vecin:graf[nod]){
if(!vizitat[vecin] && capacitate[nod][vecin] > 0){
vizitat[vecin] = 1;
tata[vecin] = nod;
coada.push(vecin);
}
}
}
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
while(bfs()){
//daca am ajuns la destinatie, inseamna ca am gasit un nou drum si verificam fluxul maxim pe acest drum
for(auto vecin: graf[dest]){
if(vizitat[vecin] && capacitate[vecin][dest] > 0){
int flux = 1e9;
int nod = dest;
//parcurgem drumul de la destinatie la sursa si aflam fluxul maxim pe acest drum
while(nod != sursa){
flux = min(flux, capacitate[tata[nod]][nod]);
nod = tata[nod];
}
//actualizam fluxul maxim
maxFlux += flux;
//actualizam capacitatea muchiilor
nod = dest;
while(nod != sursa){
capacitate[tata[nod]][nod] -= flux;
capacitate[nod][tata[nod]] += flux;
nod = tata[nod];
}
}
}
}
return maxFlux;
}
int main() {
f>>l>>r>>m;
n = l + r + 2;
sursa = 0;
dest = n - 1;
graf.resize(n);
vizitat.resize(n);
tata.resize(n); //tata[i] = nodul din care am ajuns in nodul i
capacitate.resize(n, vector<int>(n)); //capacitatea maxima a muchiei (i,j)
for(int i = 1; i <= m; i++){
int x, y;
f>>x>>y;
graf[x].push_back(y + l);
graf[y + l].push_back(x);
capacitate[x][y + l] = 1;
}
//adaugam un nod sursa care va fi nodul 1 si un nod destinatie care va fi nodul n+2
//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
for(int i = 1; i <= l; i++){
graf[sursa].push_back(i);
graf[i].push_back(sursa);
capacitate[sursa][i] = 1;
}
for(int i = l + 1; i <= n - 1; i++){
graf[i].push_back(dest);
graf[dest].push_back(i);
capacitate[i][dest] = 1;
}
// //afisare matrice de capacitate
// for(int i = 0; i < n; i++){
// for(int j = 0; j < n; j++)
// cout<<capacitate[i][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(int i = 1; i <= l; i++){
for(auto vecin: graf[i]){
if(capacitate[i][vecin] == 0 && vecin != sursa && vecin != dest){
g<<i<<" "<<vecin - l<<"\n";
}
}
}
return 0;
}