Pagini recente » Cod sursa (job #3240114) | Cod sursa (job #521091) | Cod sursa (job #1616628) | Cod sursa (job #2910056) | Cod sursa (job #2961175)
#include <fstream>
#include <iostream>
#include <vector>
#include <queue>
#include <unordered_map>
#include <string.h>
using namespace std;
ifstream in("cuplaj.in");
ofstream out("cuplaj.out");
const int NMAX = 1e5 + 5;
int Father[NMAX], N, M, E, Source, Destination, TotalFlow;
bool Seen[NMAX];
unordered_map < int, int > Edges[NMAX];
queue < int > Q;
int BFS()
{
int X, Flow = 0, Bottleneck;
Father[0] = -1;
memset(Seen, 0, sizeof(int) * (Destination + 1));
Seen[0] = 1;
Q.push(0);
while(!Q.empty())
{
X = Q.front();
Q.pop();
for(auto& newX : Edges[X])
{
if(newX.first == Destination)
continue;
if(!Seen[newX.first] && Edges[X][newX.first] > 0)
Q.push(newX.first), Seen[newX.first] = 1, Father[newX.first] = X;
}
}
for(int i = N + 1; i < Destination; i++)
{
if(!Seen[i])
continue;
X = i;
Bottleneck = Edges[X][Destination];
while(Father[X] != -1 || Bottleneck == 0)
{
Bottleneck = min(Bottleneck, Edges[Father[X]][X]);
X = Father[X];
}
if(Bottleneck == 0)
continue;
Flow += Bottleneck;
X = i;
Edges[X][Destination] -= Bottleneck;
Edges[Destination][X] += Bottleneck;
while(Father[X] != -1)
{
Edges[Father[X]][X] -= Bottleneck;
Edges[X][Father[X]] += Bottleneck;
X = Father[X];
}
}
return Flow;
}
void MaxFlow()
{
int c = BFS();
while(c)
{
TotalFlow += c;
c = BFS();
}
}
int main()
{
int x, y;
in >> N >> M >> E;
Destination = N + M + 1;
for(int i = 1; i <= E; i++)
{
in >> x >> y;
y += N;
Edges[x][y] = 1;
Edges[y][x] = 0;
}
for(int i = 1; i <= N; i++)
Edges[0][i] = 1;
for(int i = N + 1; i < Destination; i++)
Edges[i][Destination] = 1;
MaxFlow();
out << TotalFlow << '\n';
for(int i = 1; i <= N; i++)
for(auto& it : Edges[i])
if(!Edges[i][it.first] && it.first)
{
out << i << ' ' << it.first - N << '\n';
break;
}
return 0;
}