Pagini recente » Cod sursa (job #1968904) | Cod sursa (job #994184) | Cod sursa (job #358127) | Cod sursa (job #813584) | Cod sursa (job #2962363)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <climits>
using namespace std;
ifstream f("cuplaj.in");
ofstream g("cuplaj.out");
int n,m,e, sursa, destinatie,nr,flux;
struct muchie{
int pleaca,ajunge,capacitate,pozitie;
};
vector<muchie> graf;
vector<vector<int>> ind; // retine pentru fiecare nod indicii muchiilor incidente
vector<bool> vizitat;
vector<int> tata;
bool bfs(){
tata.clear();
tata.resize(nr+1);
vizitat.clear();
vizitat.resize(nr+1,false);
vizitat[sursa]= true;
queue<int> coada;
coada.push(sursa);
while(!coada.empty()){
int nod=coada.front();
coada.pop();
if(nod!=destinatie){
for (int i : ind[nod]) {
muchie mc = graf[i];
if(!vizitat[mc.ajunge] && mc.capacitate!=0){
tata[mc.ajunge]=i;
coada.push(mc.ajunge);
vizitat[mc.ajunge]=true;
}
}
}
}
return vizitat[destinatie];
}
int main() {
// Complexitatea este O(n*m*m)
int x,y;
f>>n>>m>>e;
nr=n+m+2;
sursa=0;
destinatie=nr-1;
ind.resize(nr+1);
for (int i = 0; i < e; ++i) {
f>>x>>y;
int poz=graf.size();
muchie mc;
ind[y+n].push_back(poz+1); // adaugam muchia
mc={x,y+n,1,poz+1};
graf.push_back(mc);
ind[x].push_back(poz); // adaugam muchia inversa
mc={y+n,x,0,poz};
graf.push_back(mc);
}
// Adaugam muchii din sursa in nodurile din multimea L
for (int i = 1; i <= n; ++i) {
int poz=graf.size();
muchie mc;
ind[i].push_back(poz+1);
mc={sursa,i,1,poz+1};
graf.push_back(mc);
ind[sursa].push_back(poz);
mc={i,sursa,0,poz};
graf.push_back(mc);
}
// Adaugam muchii din nodurile din multimea R in destinatie
for (int i = 1; i <= m; ++i) {
int poz=graf.size();
muchie mc;
ind[destinatie].push_back(poz+1);
mc={i+n,destinatie,1,poz+1};
graf.push_back(mc);
ind[i+n].push_back(poz);
mc={destinatie,i+n,0,poz};
graf.push_back(mc);
}
while(bfs()){ // cat timp exista un drum din sursa in destinatie
for(int i : ind[destinatie]){
muchie mc = graf[i];
if(vizitat[mc.ajunge] && graf[mc.pozitie].capacitate!=0){
tata[destinatie]=mc.pozitie;
int minim=INT_MAX; // calculam minimul din drum
for (int nod = destinatie; nod != sursa; nod = graf[tata[nod]].pleaca) {
minim = min(minim, graf[tata[nod]].capacitate);
}
for (int nod = destinatie; nod != sursa; nod = graf[tata[nod]].pleaca){
graf[tata[nod]].capacitate -= minim; // actualizam graful rezidual
graf[graf[tata[nod]].pozitie].capacitate += minim;
}
flux += minim;
}
}
}
g<<flux<<'\n';
for(muchie mc :graf){
// afisam muchiile saturate care au nodul de plecare in multimea L si cel in care ajunge din multimea R
if(mc.pleaca<mc.ajunge && mc.pleaca!=sursa && mc.ajunge!=destinatie && mc.capacitate==0){
g<<mc.pleaca<<' '<<mc.ajunge-n<<'\n';
}
}
return 0;
}