Pagini recente » Cod sursa (job #1180854) | Cod sursa (job #2445278) | Cod sursa (job #1572444) | Cod sursa (job #1292812) | Cod sursa (job #2499321)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("cuplaj.in");
ofstream fout("cuplaj.out");
const int INF = 1000000;
struct Edge{
int dest;
int flow;
int capacity;
int rev;
};
class Residual_graph{
public:
int V;
vector<Edge> *G;
int *level;
public:
Residual_graph( int n ) {
this->V = n;
G = new vector<Edge>[V + 1];
level = new int[V + 1];
}
void add_edge( int u, int v, int cap ) {
Edge a{v, 0, cap, G[v].size()};
Edge b{u, 0, 0, G[u].size()};
G[u].push_back(a);
G[v].push_back(b);
}
bool BFS( int source, int sink );
int push_flow( int node, int sink, int flow, int start[] );
int Dinic( int source, int sink );
};
bool Residual_graph::BFS( int source, int sink ) {
for( int i = 1; i <= V; i ++ )
level[i] = -1;
level[source] = 0;
queue<int> q;
q.push(source);
while( !q.empty() ) {
int node = q.front();
q.pop();
for( auto it : G[node] )
if( level[it.dest] == -1 && it.flow < it.capacity ) {
level[it.dest] = level[node] + 1;
q.push(it.dest);
}
}
return (level[sink] > 0);
}
int Residual_graph::push_flow( int node, int sink, int flow, int start[] ) {
if( node == sink )
return flow;
for( ; start[node] < G[node].size(); start[node] ++ ) {
Edge &e = G[node][start[node]];
if( level[e.dest] == level[node] + 1 && e.flow < e.capacity ) {
int tempflow = push_flow(e.dest, sink, min(e.capacity - e.flow, flow), start);
if( tempflow > 0 ) {
e.flow += tempflow;
G[e.dest][e.rev].flow -= tempflow;
return tempflow;
}
}
}
return 0;
}
int Residual_graph::Dinic( int source, int sink ) {
int totalflow = 0;
while( BFS(source, sink) == true ) {
int start[V + 1] = {0};
while( int maxflow = push_flow(source,sink,INF,start) )
totalflow += maxflow;
}
return totalflow;
}
int main() {
int n, m, e;
fin>>n>>m>>e;
Residual_graph graph(n + m + 2);
for( int i = 1; i <= e; i ++ ) {
int a, b, c;
fin>>a>>b;
b += n;
graph.add_edge(a, b, 1);
graph.add_edge(b, a, 1);
}
int super_source = n + m + 1;
int super_sink = n + m + 2;
for( int i = 1; i <= n; i ++ )
graph.add_edge(super_source, i, 1);
for( int i = n + 1; i <= n + m; i ++ )
graph.add_edge(i, super_sink, 1);
fout<<graph.Dinic(super_source,super_sink)<<"\n";
for( int i = 1; i <= n + m; i ++ ) {
for( auto it : graph.G[i] )
if( it.flow == 1 && it.dest != super_sink && it.dest != super_source )
fout<<i<<" "<<it.dest<<"\n";
}
return 0;
}