Pagini recente » Cod sursa (job #2257580) | Cod sursa (job #1312694) | Cod sursa (job #37990) | Cod sursa (job #2069299) | Cod sursa (job #2962691)
#include <fstream>
#include <vector>
#include <queue>
#include <iostream>
using namespace std;
ifstream f ("cuplaj.in");
ofstream g ("cuplaj.out");
int n, m, cardL, cardR, fluxmaxim;
vector<vector<int>> graf(202, vector<int>(20000, 0));
vector<vector<int>> lista_ad;
vector<int> parinte;
vector<bool> vizitat;
queue <int> coada;
// Metoda de rezolvare este asemanatoare cu cea a "No prime sum" de pe csacademy sau "Harta" de pe IA
// Mai exact:
// - adaug un nod sursa
// - adaug un nod terminal
// - impart nodurile in 2 multimi (prima are cardL noduri, iar a doua cardR)
// - adaug muchii intre sursa si prima multime de noduri
// - adaug muchii intre nodurile din a doua multime si terminal
// - adaug flux pe muchii (1 peste tot)
// - intre nodurile din multimi diferite adaug muchii, tot cu fluxul 1
// Mai departe algoritmul este acelasi ca la FluxMaxim
bool bfs() {
coada = queue <int> (); // golesc coada
fill(vizitat.begin(), vizitat.end(), false);
fill(parinte.begin(), parinte.end(), -1);
coada.push(0);
vizitat[0] = true;
while (!coada.empty()) {
int nod = coada.front();
coada.pop();
for (auto vec: lista_ad[nod]) {
if (!vizitat[vec] && graf[nod][vec] > 0) {
parinte[vec] = nod;
coada.push(vec);
vizitat[vec] = true;
}
}
}
return vizitat[n + 1];
}
void FluxMaxim() {
while (bfs()) {
for (auto vec: lista_ad[n + 1])
{
if (!(vizitat[vec] && graf[vec][n + 1] != 0))
continue;
int aux = vec, capacitateMaxima = 1;
while (aux != 0) {
if (graf[parinte[aux]][aux] == 0) {
capacitateMaxima = 0;
break;
}
aux = parinte[aux];
}
if (capacitateMaxima == 1) {
aux = vec;
graf[aux][n + 1] -= capacitateMaxima;
graf[n + 1][aux] += capacitateMaxima;
while (aux != 0) {
graf[parinte[aux]][aux] -= capacitateMaxima;
graf[aux][parinte[aux]] += capacitateMaxima;
aux = parinte[aux];
}
fluxmaxim += capacitateMaxima;
}
}
}
g << fluxmaxim << "\n";
// Parcurgem nodurile din prima multime
// Pentru fiecare vecin al fiecarui nod din prima multime
// Daca nu e sursa sau terminalul si daca capacitatatea ramasa pe muchia de la i la lista_ad[i][j] (vec) e 0, il afisam
for (int i = 1; i <= cardL; i++)
for (auto nod: lista_ad[i])
if (graf[i][nod] == 0 && nod != 0 && nod != n + 1)
g << i << " " << nod - cardL << "\n";
}
int main()
{
f >> cardL >> cardR >> m;
n = cardL + cardR;
lista_ad.resize(n + 2);
vizitat.resize(n + 2);
parinte.resize(n + 2);
graf = vector<vector<int>> (n + 2, vector<int>(n + 2, 0));
// - Adaug nodul sursa, il conectez la toate nodurile din prima multime
// si pun fluxul 1 pe fiecare muchie de la sursa la nod
for (int u = 1; u <= cardL; u++) {
graf[0][u] = 1;
lista_ad[0].push_back(u);
lista_ad[u].push_back(0);
}
// -> Adaug nodul terminal, il conectez la toate nodurile din a doua multime
// si pun fluxul 1 pe fiecare muchie de la sursa la nod
for (int u = cardL + 1; u <= n; u++) {
graf[u][n + 1] = 1;
lista_ad[n + 1].push_back(u);
lista_ad[u].push_back(n + 1);
}
// - Acum citesc cele e muchii si le pun in lista
int u, v;
for (int i = 0; i < m; i++) {
f >> u >> v;
graf[u][v + cardL] = 1;
lista_ad[u].push_back(v + cardL); // adun n ca sa le pun in a doua multime
lista_ad[v + cardL].push_back(u);
}
FluxMaxim();
return 0;
}