Pagini recente » Cod sursa (job #1602747) | Cod sursa (job #690048) | Cod sursa (job #2817529) | Cod sursa (job #961919) | Cod sursa (job #2962749)
#include <fstream>
#include <vector>
#include <queue>
#include <bitset>
using namespace std;
ifstream fin("cuplaj.in");
ofstream fout("cuplaj.out");
struct Edge {
int x, y, cap, poz;
};
int n, m, e, s, d, x, y;
vector <Edge> edges;
vector <vector<int>> v;
vector <int> t;
bitset<20010> visited;
bool bfs() {
visited.reset();
queue <int> q;
q.push(s);
visited[s] = true;
int node;
while(!q.empty()) {
node = q.front();
q.pop();
if(node == d)
continue;
for(auto it : v[node]) {
Edge edge = edges[it];
if(!visited[edge.y] && edge.cap) {
t[edge.y] = it;
visited[edge.y] = true;
q.push(edge.y);
}
}
}
return visited[d];
}
// algoritmul lui Edmonds-Karp pentru flux maxim
int getMaxFlow() {
int answer = 0;
while(bfs()) {
for(auto it : v[d]) {
if(!visited[edges[it].y])
continue;
Edge edge = edges[it];
t[d] = edge.poz;
int minFlow = 2e9;
for (int node = d; node != s; node = edges[t[node]].x) {
if (edges[t[node]].cap < minFlow)
minFlow = edges[t[node]].cap;
}
if(minFlow == 0)
continue;
answer += minFlow;
for (int node = d; node != s; node = edges[t[node]].x) {
edges[t[node]].cap -= minFlow;
edges[edges[t[node]].poz].cap += minFlow;
}
}
}
return answer; // fluxul maxim = cuplajul maxim
}
int main() {
fin >> n >> m >> e;
d = n + m + 1;
v = vector <vector<int>> (n + m + 2);
t = vector <int> (n + m + 2);
// adaugam muchiile de la nodurile din stanga la cele din dreapta
for(int i = 1; i <= e; i ++) {
fin >> x >> y;
int dim = edges.size();
v[x].push_back(dim);
v[y + n].push_back(dim + 1);
edges.push_back({x, y + n, 1, dim + 1});
edges.push_back({y + n, x, 0, dim});
}
// adaugam muchiile de la sursa la nodurile din stanga
for(int i = 1; i <= n; i ++) {
int dim = edges.size();
v[s].push_back(dim);
v[i].push_back(dim + 1);
edges.push_back({s, i, 1, dim + 1});
edges.push_back({i, s, 0, dim});
}
// adaugam muchiile de la nodurile din dreapta la destinatie
for(int i = n + 1; i <= n + m; i ++) {
int dim = edges.size();
v[i].push_back(dim);
v[d].push_back(dim + 1);
edges.push_back({i, d, 1, dim + 1});
edges.push_back({d, i, 0, dim});
}
fout << getMaxFlow() << '\n';
// afisam muchiile care fac parte din cuplaj = muchiile saturate
for(auto edge : edges)
if(edge.x < edge.y && edge.x != s && edge.y != d && edge.cap == 0)
fout << edge.x << " " << edge.y - n << '\n';
return 0;
}