Pagini recente » Cod sursa (job #2763302) | Cod sursa (job #1858996) | Cod sursa (job #2248858) | Cod sursa (job #3142933) | Cod sursa (job #2958538)
#include <bits/stdc++.h>
using namespace std;
ifstream f("cuplaj.in");
ofstream g("cuplaj.out");
const int NMAX = 20002;
struct edge{
int node, flow, capacity;
};
int n, m, e;
vector<edge> G[NMAX];
vector<edge> adjacent;
void add_edge(int x, int y){
G[x].push_back({y, 0, 1});
G[y].push_back({x, 0, 0});
if(y == n + m + 1)
adjacent.push_back({x, 0, 1});
}
void read(){
f >> n >> m >> e;
for(int i = 1; i <= e; ++i){
int x, y;
f >> x >> y;
add_edge(x , n + y);
}
}
bool BFS(int s, int t, vector<pair<int, int>>& parent){
fill(parent.begin(), parent.end(), make_pair(-1, -1));
queue<int> Q;
Q.push(s);
parent[s].first = -2;
while(!Q.empty()){
int node = Q.front();
Q.pop();
for(int i = 0; i < (int) G[node].size(); ++i){
auto& link = G[node][i];
if(parent[link.node].first == -1 && link.capacity - link.flow > 0){
parent[link.node].first = node;
parent[link.node].second = i;
if(link.node == t)
return true;
Q.push(link.node);
}
}
}
return false;
}
void solve(){
int max_flow = 0, s = 0, t = n + m + 1;
vector<pair<int, int>> parent(n + m + 3, make_pair(-1, -1)); // node, index
for(int i = 1; i <= n; ++i)
add_edge(s, i);
for(int i = 1; i <= m; ++i)
add_edge(n + i, t);
while(BFS(s, t, parent)){
for(auto& x : adjacent){
if(x.capacity == 0 || parent[x.node].first == -1)
continue;
int path_flow = INT_MAX;
parent[t].first = x.node;
for(int i = 0; i < (int) G[x.node].size(); ++i)
if(G[x.node][i].node == t){
parent[t].second = i;
break;
}
// find the max flow through the path
for(int node = t; node != s; node = parent[node].first){
int aux = parent[node].first, index_node = parent[node].second;
path_flow = min(path_flow, G[aux][index_node].capacity - G[aux][index_node].flow);
}
// update
for(int node = t; node != s; node = parent[node].first){
int aux = parent[node].first, index_aux, index_node = parent[node].second;
for(index_aux = 0; index_aux < G[node].size(); ++index_aux)
if(G[node][index_aux].node == aux)
break;
if(path_flow > 0){
G[aux][index_node].flow += path_flow;
G[node][index_aux].flow -= path_flow;
}
}
max_flow += path_flow;
}
}
g << max_flow << '\n';
for(int node = 1; node <= n; ++node){
for(auto& link : G[node])
if(link.flow == 1)
g << node << ' ' << link.node - n << '\n';
}
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
read();
solve();
f.close();
g.close();
return 0;
}