Pagini recente » Cod sursa (job #1349168) | Cod sursa (job #1810907) | Cod sursa (job #424584) | Cod sursa (job #1157010) | Cod sursa (job #2958589)
/*
* Edmonds-Karp's algorithm
* https://www.infoarena.ro/problema/cuplaj
*/
#include <bits/stdc++.h>
using namespace std;
ifstream in("cuplaj.in");
ofstream out("cuplaj.out");
int leftSize, rightSize, edges, s, t;
vector<pair<int, int>> parrent, inDest;
vector<vector<pair<int, pair<int, int>>>> adjListRes;
void addEdge(int u, int v){
adjListRes[u].push_back({v, {1, adjListRes[v].size()}});
adjListRes[v].push_back({u, {0, adjListRes[u].size()-1}});
if(v == t)
inDest.emplace_back(u, adjListRes[u].size()-1);
}
void init() {
s = 0;
t = leftSize+rightSize+1;
parrent.resize(t+1);
adjListRes.resize(t+1);
for(int i = 1; i <= leftSize; i++)
addEdge(s, i);
for(int i = 1; i <= rightSize; i++)
addEdge(leftSize+i, t);
}
void read(){
in >> leftSize >> rightSize >> edges;
init();
for(int i = 1; i <= edges; i++){
int u, v;
in >> u >> v;
addEdge(u, leftSize + v);
}
}
bool bf(){
vector<bool> visited(t+1);
queue<int> q;
q.push(s);
visited[s] = true;
parrent[s] = {-1, -1};
while(!q.empty()){
int u = q.front();
q.pop();
if(u == t)
continue;
int i = 0;
for(auto node: adjListRes[u]){
int v, c; // node, capacity
v = node.first;
c = node.second.first;
if(!visited[v] and c){
parrent[v] = {u, i}; // adjListRes[u][i].first == v
visited[v] = true;
q.push(v);
}
i++;
}
}
return visited[t];
}
int maxFlow(){
long max_flow = 0;
while(bf()) {
for (auto node: inDest) {
int u, v, i, j, min_path = 1;
parrent[t] = node;
v = t;
while (parrent[v].first != -1) {
u = parrent[v].first;
i = parrent[v].second;
min_path = min(min_path, adjListRes[u][i].second.first);
v = u;
}
v = t;
while (parrent[v].first != -1) {
u = parrent[v].first;
i = parrent[v].second;
j = adjListRes[u][i].second.second;
adjListRes[u][i].second.first -= min_path;
adjListRes[v][j].second.first += min_path;
v = u;
}
max_flow += min_path;
}
}
return max_flow;
}
int main(){
read();
out << maxFlow() << '\n';
for(int u = 1; u <= leftSize; u++)
for(auto node: adjListRes[u]){
int v = node.first;
int c = node.second.first;
if(v && c == 0)
out << u << " " << v-leftSize << endl;
}
return 0;
}