Pagini recente » Istoria paginii utilizator/omega91 | Istoria paginii utilizator/ioi_anu_v_iitor | Diferente pentru algoritmiada-2019/runda-maraton/solutii/pisica intre reviziile 6 si 7 | Cod sursa (job #2756989) | Cod sursa (job #2962743)
#include <fstream>
#include <bitset>
#include <vector>
#include <queue>
#include <climits>
using namespace std;
ifstream fin("cuplaj.in");
ofstream fout("cuplaj.out");
struct muchie{
int iesire, intrare, cap, index;
};
vector<muchie> muchii;
int n, m, e, x, y, fluxmax = 0;;
bitset<20010> f;
vector <int> t;
vector<vector<int>> graf;
bool bfs() {
queue<int> q;
t.clear();
t.resize(n + m + 2);
f.reset();
q.push(0);
f[0] = true;
while (!q.empty()) {
int nod = q.front();
q.pop();
for (int it : graf[nod]) {
muchie muchie = muchii[it];
if (!f[muchie.intrare] && muchie.cap > 0) {
t[muchie.intrare] = it;
q.push(muchie.intrare);
f[muchie.intrare] = true;
}
}
}
return f[n + m + 1];
}
int main(){
fin >> n >> m >> e;
graf.resize(n + m + 2);
for (int i = 1; i <= e; i++){
fin >> x >> y;
muchii.push_back({x, y + n, 1, 2 * i - 1});
muchii.push_back({y + n, x, 0, 2 * i - 2});
graf[y + n].push_back(2 * i - 1);
graf[x].push_back(2 * i - 2);
}
int nrmuchii = int(muchii.size());
// adaugam muchiile de la sursa la nodurile din partea stanga
for (int i = 1; i <= n; i++){
nrmuchii += 2;
muchii.push_back({0, i, 1, nrmuchii - 1 });
graf[i].push_back(nrmuchii - 1);
muchii.push_back({i, 0, 0, nrmuchii - 2});
graf[0].push_back(nrmuchii - 2);
}
// adaugam muchiile de la nodurile din partea dreapta la destinatie
for (int i = n + 1; i < n + m + 2 - 1; i++){
nrmuchii += 2;
muchii.push_back({i, n + m + 1, 1, nrmuchii - 1 });
graf[n + m + 1].push_back(nrmuchii - 1);
muchii.push_back({n + m + 1, i, 0, nrmuchii - 2});
graf[i].push_back(nrmuchii - 2);
}
// algoritmul Ford-Fulkerson pentru flux maxim
while (bfs()){
for (auto vecin : graf[n + m + 1]) {
muchie muchie = muchii[vecin];
if (f[muchie.intrare] && muchii[muchie.index].cap != 0) {
int nod = n + m + 1;
t[n + m + 1] = muchie.index;
int fluxmin = INT_MAX;
while (nod != 0){
if (fluxmin > muchii[t[nod]].cap)
fluxmin = muchii[t[nod]].cap;
nod = muchii[t[nod]].iesire;
}
nod = n + m + 1;
while (nod != 0){
muchii[t[nod]].cap -= fluxmin;
muchii[muchii[t[nod]].index].cap += fluxmin;
nod = muchii[t[nod]].iesire;
}
fluxmax += fluxmin;
}
}
}
// fluxul maxim este egal cu cuplajul maxim
fout << fluxmax << "\n";
// afisam muchiile saturate, adica cele care fac parte din cuplajul maxim
for (auto muchie : muchii){
if (muchie.cap == 0 && muchie.iesire != 0 && muchie.intrare != n + m + 1 && muchie.iesire < muchie.intrare)
{
fout << muchie.iesire << " " << muchie.intrare - n << "\n";
}
}
return 0;
}