Pagini recente » Cod sursa (job #2589418) | Cod sursa (job #2819487) | Cod sursa (job #1395161) | Cod sursa (job #1352197) | Cod sursa (job #2888487)
#include <bits/stdc++.h>
using namespace std;
class Edge{
public:
int from;
int to;
int capacity;
int flow;
Edge* reverseEdge;
Edge(int from, int to, int capacity, int flow = 0, Edge* reverseEdge = NULL):
from(from), to(to), capacity(capacity), flow(flow), reverseEdge(reverseEdge){}
~Edge(){
reverseEdge = NULL;
}
int getRemainingCapacity() const{
return capacity - flow;
}
bool isSaturated() const{
return (flow == capacity);
}
};
class Graph{
public:
const int N;
vector<vector<Edge*>> edges;
public:
Graph(const int& N): N(N){
edges.resize(N);
}
~Graph(){
for(int i = 0; i < (int)edges.size(); ++i){
for(int j = 0; j < (int)edges[i].size(); ++j){
delete edges[i][j];
}
}
edges.clear();
}
void addEdge(int from, int to, int c){
Edge* edge1 = new Edge(from, to, c);
Edge* edge2 = new Edge(to, from, 0);
edge1->reverseEdge = edge2;
edge2->reverseEdge = edge1;
edges[from].push_back(edge1);
edges[to].push_back(edge2);
}
};
class Dinic{
private:
const Graph& G;
const int N;
const int SRC;
const int DEST;
const int INF = 1e8;
vector<int> dist;
vector<int> startEdgeIdx;
int bfs(){
fill(dist.begin(), dist.end(), INF);
queue<int> q;
q.push(SRC);
dist[SRC] = 0;
while(!q.empty() && dist[DEST] == INF){
int node = q.front();
q.pop();
for(Edge* edge: G.edges[node]){
int node = edge->from;
int nextNode = edge->to;
if(edge->getRemainingCapacity() > 0 && dist[nextNode] == INF){
dist[nextNode] = 1 + dist[node];
q.push(nextNode);
}
}
}
return (dist[DEST] != INF);
}
int dfs(int node, int minDelta){
if(node == DEST){
return minDelta;
}
for(; startEdgeIdx[node] < (int)G.edges[node].size(); ++startEdgeIdx[node]){
Edge* edge = G.edges[node][startEdgeIdx[node]];
int nextNode = edge->to;
if(edge->getRemainingCapacity() > 0 && dist[node] + 1 == dist[nextNode]){
int delta = dfs(nextNode, min(minDelta, edge->getRemainingCapacity()));
if(delta > 0){
edge->flow += delta;
edge->reverseEdge->flow -= delta;
return delta;
}
}
}
return 0;
}
public:
Dinic(const Graph& G, const int& SRC, const int& DEST):
G(G), N(G.N), SRC(SRC), DEST(DEST){
}
int computeMaxFlow(){
dist.resize(N);
startEdgeIdx.resize(N);
int maxFlow = 0;
while(bfs()){
fill(startEdgeIdx.begin(), startEdgeIdx.end(), 0);
int delta = INF;
while(delta > 0){
delta = dfs(SRC, INF);
maxFlow += delta;
}
}
return maxFlow;
}
};
int main(){
ifstream cin("cuplaj.in");
ofstream cout("cuplaj.out");
int N, M, E;
cin >> N >> M >> E;
const int TOTAL_NODES = N + M + 5;
const int SRC = TOTAL_NODES - 2;
const int DEST = TOTAL_NODES - 1;
Graph G(TOTAL_NODES);
int x, y;
for(int i = 1; i <= E; ++i){
cin >> x >> y;
G.addEdge(x, N + y, 1);
}
for(int x = 1; x <= N; ++x){
G.addEdge(SRC, x, 1);
}
for(int y = N + 1; y <= N + M; ++y){
G.addEdge(y, DEST, 1);
}
Dinic dinic(G, SRC, DEST);
int maxMatching = dinic.computeMaxFlow();
cout << maxMatching << "\n";
for(int node = 1; node <= N; ++node){
for(Edge* edge: G.edges[node]){
if(edge->isSaturated() &&
edge->from != SRC && edge->to != SRC &&
edge->from != DEST && edge->to != DEST){
cout << edge->from << " " << (edge->to - N) << "\n";
}
}
}
cin.close();
cout.close();
return 0;
}