Pagini recente » Cod sursa (job #2487264) | Cod sursa (job #1107679) | Cod sursa (job #1163399) | Cod sursa (job #1009581) | Cod sursa (job #2962693)
#include <fstream>
#include <vector>
#include <queue>
#include <string.h>
using namespace std;
ifstream in("cuplaj.in");
ofstream out("cuplaj.out");
struct Edge
{
int X, Y, Flow, Position;
};
const int NMAX = 1e4 + 5, MMAX = 3e5 + 5;
int Father[NMAX], N, M, E, Source, Destination, TotalFlow, nrEdges = -1;
bool Seen[NMAX];
vector < int > Graph[NMAX];
Edge Edges[MMAX];
queue < int > Q;
int BFS()
{
int X, Flow = 0, Bottleneck;
memset(Seen, 0, Destination + 1);
Seen[Source] = 1;
Q.push(Source);
while(!Q.empty())
{
X = Q.front();
Q.pop();
for(int newX : Graph[X])
{
if(Edges[newX].Y == Destination)
continue;
if(!Seen[Edges[newX].Y] && Edges[newX].Flow > 0)
Q.push(Edges[newX].Y), Seen[Edges[newX].Y] = 1, Father[Edges[newX].Y] = newX;
}
}
for(int it : Graph[Destination])
{
if(!Seen[Edges[it].Y] || Edges[Edges[it].Position].Flow == 0)
continue;
Bottleneck = 2;
Father[Destination] = Edges[it].Position;
for(int x = Destination; x != Source; x = Edges[Father[x]].X)
Bottleneck = min(Bottleneck, Edges[Father[x]].Flow);
Flow += Bottleneck;
for(int x = Destination; x != Source; x = Edges[Father[x]].X)
Edges[Father[x]].Flow -= Bottleneck, Edges[Edges[Father[x]].Position].Flow += Bottleneck;
}
return Flow;
}
int main()
{
int x, y;
in >> N >> M >> E;
Destination = N + M + 1;
for(int i = 1; i <= E; i++)
{
in >> x >> y;
Edges[++nrEdges].X = x;
Edges[nrEdges].Y = N + y;
Edges[nrEdges].Flow = 1;
Edges[nrEdges].Position = nrEdges + 1;
Graph[x].push_back(nrEdges);
Edges[++nrEdges].X = y + N;
Edges[nrEdges].Y = x;
Edges[nrEdges].Flow = 0;
Edges[nrEdges].Position = nrEdges - 1;
Graph[y].push_back(nrEdges);
}
for(int i = 1; i <= N; i++)
{
Edges[++nrEdges].X = Source;
Edges[nrEdges].Y = i;
Edges[nrEdges].Flow = 1;
Edges[nrEdges].Position = nrEdges + 1;
Graph[Source].push_back(nrEdges);
Edges[++nrEdges].X = i;
Edges[nrEdges].Y = Source;
Edges[nrEdges].Flow = 0;
Edges[nrEdges].Position = nrEdges - 1;
Graph[i].push_back(nrEdges);
}
for(int i = N + 1; i < Destination; i++)
{
Edges[++nrEdges].X = i;
Edges[nrEdges].Y = Destination;
Edges[nrEdges].Flow = 1;
Edges[nrEdges].Position = nrEdges + 1;
Graph[i].push_back(nrEdges);
Edges[++nrEdges].X = Destination;
Edges[nrEdges].Y = i;
Edges[nrEdges].Flow = 0;
Edges[nrEdges].Position = nrEdges - 1;
Graph[Destination].push_back(nrEdges);
}
x = BFS();
while (x)
{
TotalFlow += x;
x = BFS();
}
out << TotalFlow << '\n';
for(Edge &it : Edges)
if(it.Flow == 0 && it.X != 0 && it.Y != Destination && it.X < it.Y)
out << it.X << ' ' << it.Y - N << '\n';
return 0;
}