Pagini recente » Cod sursa (job #506833) | Cod sursa (job #2208993) | Cod sursa (job #100462) | Cod sursa (job #1254608) | Cod sursa (job #2961465)
#include <fstream>
#include <vector>
#include <queue>
#define INT_MAX 2147483647;
using namespace std;
//1. a) cuplaj maxim in graf bipartit
int n, m, cardN, cardM, maxFlow, start, final;
vector<vector<int>> adj, rez;
vector<int> anc;
vector<bool> viz;
//parcurgerea bfs care gaseste lanturi de la start la final:
bool bfs() {
queue<int> q;
anc.clear();
anc.resize(n + 2, -1);
viz.clear();
viz.resize(n + 2, false);
q.push(start);
viz[start] = true;
while (!q.empty()) {
int curr = q.front();
q.pop();
if (curr == final)
continue;
for (int i = 0; i < adj[curr].size(); i++) {
if (!viz[adj[curr][i]] && rez[curr][adj[curr][i]] > 0) {
anc[adj[curr][i]] = curr;
q.push(adj[curr][i]);
viz[adj[curr][i]] = true;
}
}
}
return viz[final];
}
//algoritmul edmonds-karp:
void edmondsKarp() {
//cat timp mai exista lanturi care pot fi parcurse de la start la final, continuam sa le parcurgem adaugand flux:
while (bfs()) {
//pentru toate drumurile care au dus la final:
for (int i = 0; i < adj[final].size(); i++)
{
if (!(viz[adj[final][i]] && rez[adj[final][i]][final] != 0))
continue;
//caut bottleneck-ul, reprezentand noul flux:
int aux = adj[final][i], min = 1;
while (aux != start) {
if (rez[anc[aux]][aux] == 0) {
min = 0;
break;
}
aux = anc[aux];
}
//updatez matricea reziduala, adaugand noul flux:
if (min == 1) {
aux = adj[final][i];
rez[aux][final] -= min;
rez[final][aux] += min;
while (aux != start) {
rez[anc[aux]][aux] -= min;
rez[aux][anc[aux]] += min;
aux = anc[aux];
}
maxFlow += min;
}
}
}
}
//citirea datelor: informatiile despre cele 2 multimi sunt modelate sub forma unui graf orientat bipartit la care vom adauga doua noduri suplimentare, start(0) si final(n+1),
//iar fiecare arc va avea o capacitate de 1
void citire() {
ifstream fin("cuplaj.in");
int nod1, nod2;
fin >> cardN >> cardM >> m;
n = cardN + cardM;
adj.resize(n + 2);
rez.resize(n + 2, vector<int>(n + 2, 0));
start = 0;
final = n + 1;
for (int nod = 1; nod <= cardN; nod++) {
adj[start].push_back(nod);
adj[nod].push_back(start);
rez[start][nod] = 1;
}
for (int nod = cardN + 1; nod <= n; nod++) {
adj[final].push_back(nod);
adj[nod].push_back(final);
rez[nod][final] = 1;
}
for (int i = 0; i < m; i++) {
fin >> nod1 >> nod2;
adj[nod1].push_back(nod2 + cardN);
adj[nod2 + cardN].push_back(nod1);
rez[nod1][nod2 + cardN] = 1;
}
}
void afisare() {
ofstream fout("cuplaj.out");
fout << maxFlow << "\n";
for (int i = 1; i <= cardN; i++)
for (int j = 0; j < adj[i].size(); j++)
if (rez[i][adj[i][j]] == 0 && adj[i][j] != start && adj[i][j] != final)
fout << i << " " << adj[i][j]-cardN << "\n";
fout.close();
}
int main()
{
citire();
edmondsKarp();
afisare();
return 0;
}