Pagini recente » Cod sursa (job #857898) | Cod sursa (job #3152121) | Cod sursa (job #382334) | Cod sursa (job #1189015) | Cod sursa (job #2955997)
#include <bits/stdc++.h>
#define inf INT_MAX
#define dim 20020
using namespace std;
ifstream fin("cuplaj.in");
ofstream fout("cuplaj.out");
/*
Ajutor: https://www.infoarena.ro/flux-si-cuplaj
Idee: Similar cu ce am facut la harta, adaugam un nou start si un final, orientam toate
muchiile spre final si le dam o capacitate de 1. Raspunsul va fi dat de fluxul maxim, iar
muchiile din cuplaj vor fi cele saturate, aka au ramas cu capacitate 0.
*/
long long maxFlow = 0;
int tata[dim], n, m, x, y, e, nod, flow;
bool viz[dim];
vector< int > a[10010];
bool bfs() {
queue<int> coada;
memset(tata, 0, sizeof(tata));
memset(viz, false, sizeof(viz));
coada.push(0);
viz[0] = true;
tata[0] = -1;
while(!coada.empty()) {
int front = coada.front();
coada.pop();
if(front == n + m + 1) {
return true;
}
for(int i = 1; i <= n + m + 1; i++) {
if( !viz[i] && a[front][i] > 0) {
coada.push(i);
viz[i] = true;
tata[i] = front;
}
}
}
return false;
}
int main() {
fin >> n >> m >> e;
for(int i = 0; i <= n + m + 1; i++)
a[i].resize(n + m + 1, 0);
for(int i = 0; i < e; i++) {
fin >> x >> y;
a[x][n + y] = 1;
}
for(int i = 1; i <= n; i++)
a[0][i] = 1;
for(int i = 1; i <= m; i++)
a[n + i][n + m + 1] = 1;
while(bfs()) {
for(int i = 1; i <= m; i++) {
if( viz[n + i] && a[n + i][n + m + 1] > 0 ) {
flow = inf;
tata[n + m + 1] = n + i;
for(nod = n + m + 1; nod != 0; nod = tata[nod]) {
flow = min(flow, a[ tata[nod] ][nod]);
}
if(flow == 0) continue;
for(nod = n + m + 1; nod != 0; nod = tata[nod]) {
a[ tata[nod] ][nod] -= flow;
a[nod][ tata[nod] ] += flow;
}
maxFlow += flow;
}
}
}
fout << maxFlow << '\n';
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
if( a[i][n + j] == 0 && a[n + j][i] == 1)
fout << i << " " << j << '\n';
return 0;
}