Pagini recente » Cod sursa (job #98157) | Cod sursa (job #1579804) | Cod sursa (job #1073747) | Cod sursa (job #690200) | Cod sursa (job #2960298)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
ifstream fin("cuplaj.in");
ofstream fout("cuplaj.out");
struct muchie {
int nodStart, nodStop, capacitate,poz;
};
vector<vector<int>> listaAdiacenta;
vector<muchie> muchii;
muchie mc;
vector<bool> viz;
vector<int> tata;
int n, m, e, sursa, destinatie, numarNoduri, numarMuchii;
void adaugareMuchie(int a, int b)
{
// adaugare arc direct
listaAdiacenta[b].push_back(numarMuchii+1);
mc.nodStart = a;
mc.nodStop = b ;
mc.capacitate = 1;
mc.poz = numarMuchii+1;
muchii.push_back(mc);
// adaugare arc indirect
listaAdiacenta[a].push_back(numarMuchii);
mc.nodStart = b ;
mc.nodStop = a;
mc.capacitate = 0;
mc.poz = numarMuchii;
muchii.push_back(mc);
numarMuchii+=2;
}
// citesc datele din fisier si pe baza lor imi construies reteaua de transport asociata grafului bipartit
void citire()
{
fin >> n >> m >> e;
numarNoduri = n + m + 2;
sursa = 0;
destinatie = n + m + 1;
listaAdiacenta = vector<vector<int>>(numarNoduri, vector<int>());
int a, b;
for (int i = 0; i < e; i++)
{
fin >> a >> b;
adaugareMuchie(a, b + n);
}
for (int i = 1; i <= n; i++)
{
adaugareMuchie(sursa, i);
}
for (int i = n+1; i < numarNoduri-1; i++)
{
adaugareMuchie(i, destinatie);
}
}
// functia care determina daca exista sau nu un lant nesaturat si daca exista il construieste
bool bfs()
{
tata = vector<int>(numarNoduri, 0);
viz = vector<bool>(numarNoduri, false);
queue<int> coada;
coada.push(sursa);
viz[sursa] = true;
while (!coada.empty())
{
int nod = coada.front();
coada.pop();
if (nod != destinatie)
{
for (auto index : listaAdiacenta[nod])
{
mc = muchii[index];
if (viz[mc.nodStop] == false && mc.capacitate > 0)
{
tata[mc.nodStop] = index;
coada.push(mc.nodStop);
viz[mc.nodStop] = true;
}
}
}
}
return viz[destinatie];
}
int main()
{
citire();
int maxFlow = 0;
while (bfs())
{
// parcurgem toate muchiile care pornesc din destinatie
for (auto index : listaAdiacenta[destinatie])
{
if (viz[muchii[index].nodStop] && muchii[muchii[index].poz].capacitate > 0)
{
// stabilim care este muchia prin care am ajuns la destinatie
int minFlow = 100000000;
mc = muchii[index];
tata[destinatie] = mc.poz;
int nod = destinatie;
// calculam capacitatea reziduala a lantului
while (nod != sursa)
{
minFlow = min(minFlow, muchii[tata[nod]].capacitate);
nod = muchii[tata[nod]].nodStart;
}
// revizuire fluxuri
nod = destinatie;
while (nod != sursa)
{
muchii[muchii[tata[nod]].poz].capacitate += minFlow;
muchii[tata[nod]].capacitate -= minFlow;
nod = muchii[tata[nod]].nodStart;
}
maxFlow += minFlow;
}
}
}
fout << maxFlow << endl;
for (muchie mcc : muchii)
{
if (mcc.nodStart < mcc.nodStop && mcc.nodStart != 0 && mcc.nodStop != destinatie && mcc.capacitate == 0)
{
fout << mcc.nodStart << " " << mcc.nodStop - n << "\n";
}
}
//complexitate O((n+m)^2*m)
}