Pagini recente » Cod sursa (job #1752694) | Cod sursa (job #334678) | Cod sursa (job #2084792) | Cod sursa (job #350053) | Cod sursa (job #1539805)
#include<iostream>
#include<fstream>
#include<vector>
#include<queue>
#include<bitset>
#define pb push_back
#define Nmax 20050
#define sursa 20005
#define dest 20006
#define INF 11
// algoritmul de rezolvare folosind algoritmul edmonds-karp
using namespace std;
ifstream f("cuplaj.in");
ofstream g("cuplaj.out");
int N,N1,N2,M;
bitset<Nmax> verif;
struct arc {
int d=-1,cap,flow;
arc *invers;
};
// arc.d=destinatia arcului
// arc.cap=capacitatea arcului
// arc.flow=fluxul arcului la un moment dat
// arc.invers=adresa arcului invers corespunzator arcului
#define arcp arc*
vector<arcp> v[Nmax];
arcp muchie_from_dad[Nmax];
// verif[i]=1 daca nodul i a fost verificat la parcurgerea bfs curenta
// v[i]=lista a arcelor adiacente la nodul i
// muchie_from_dad[i]=muchia de la tatal nodului i la nodul i pentru parcurgerea bfs curenta
bool bfs();
int main()
{
f>>N1>>N2>>M;
for (int i=1;i<=M;++i) { // se formeaza arcele de corespondenta intre cele 2 grafuri
int x,y;
f>>x>>y;
arc *da1=new arc;
arc *da2=new arc;
da1->d=N1+y;
da1->cap=1;
da1->flow=0;
v[x].pb(da1);
da2->d=x;
da2->cap=da2->flow=0;
v[N1+y].pb(da2);
v[x][v[x].size()-1]->invers=v[N1+y][v[N1+y].size()-1];
v[N1+y][v[N1+y].size()-1]->invers=v[x][v[x].size()-1];
}
for (int i=1;i<=N1;++i) { // se formeaza arcele adiacente la sursa
arc *da=new arc;
arc *daS=new arc;
da->d=i;
da->cap=1;
da->flow=0;
v[sursa].pb(da);
daS->d=sursa;
daS->cap=daS->flow=0;
v[i].pb(daS);
v[sursa][v[sursa].size()-1]->invers=v[i][v[i].size()-1];
v[i][v[i].size()-1]->invers=v[sursa][v[sursa].size()-1];
}
for (int i=N1+1;i<=N1+N2;++i) { // se formeaza arcele adiacente la destinatie
arc *da=new arc;
arc *daD=new arc;;
da->d=i;
da->cap=da->flow=0;
v[dest].pb(da);
daD->d=dest;
daD->cap=1;
daD->flow=0;
v[i].pb(daD);
v[dest][v[dest].size()-1]->invers=v[i][v[i].size()-1];
v[i][v[i].size()-1]->invers=v[dest][v[dest].size()-1];
}
int cuplaj=0;
while (bfs()) { // algoritmul edmonds-karp optim
vector<arcp>::iterator it;
for (it=v[dest].begin();it<v[dest].end();++it) {
arc *muchie=(*it)->invers;
if (verif.test((*it)->d) && muchie->cap!=muchie->flow) {
muchie_from_dad[dest]=muchie;
int min1=INF;
for (arc *p=muchie_from_dad[dest]; ;p=muchie_from_dad[(p->invers)->d]) {
if ((p->cap)-(p->flow)<min1) {
min1=(p->cap)-(p->flow);
}
if (((p->invers)->d)==sursa) {
break;
}
}
if (min1!=0) {
++cuplaj;
for (arc *p=muchie_from_dad[dest]; ;p=muchie_from_dad[(p->invers)->d]) {
p->flow++;(p->invers)->flow--;
if (((p->invers)->d)==sursa) {
break;
}
}
}
}
}
}
g<<cuplaj<<'\n';
for (int i=1;i<=N1;++i) {
vector<arc*>::iterator it;
for (it=v[i].begin();it<v[i].end();++it) {
if ((*it)->flow==1) {
g<<i<<' '<<((*it)->d)-N1<<'\n';
}
}
}
}
bool bfs() {
verif.reset();
queue<int> Q;
Q.push(sursa);
verif.set(sursa,1);
while (!Q.empty()) {
int nod=Q.front();
Q.pop();
if (nod==dest) {
return 1;
}
vector<arcp>::iterator it;
for (it=v[nod].begin();it<v[nod].end();++it) {
if (!verif.test((*it)->d) && (*it)->cap!=(*it)->flow) {
muchie_from_dad[(*it)->d]=(*it);
Q.push((*it)->d);
verif.set((*it)->d,1);
}
}
}
return 0;
}