Pagini recente » Cod sursa (job #2879081) | Cod sursa (job #1991221) | Cod sursa (job #1576346) | Cod sursa (job #831313) | Cod sursa (job #2961562)
/*
Am aplicat algoritmul Edmonds-Karp avand complexitatea O(n * m * m):
-> Parcurg graful prin bfs (cautand lanturi intre 1 si n, retinand si arborele bfs)
-> ma plimb din parinte in parinte pana ajung la 1 pentru a calcula minimul (locul care imi da bottleneck in lant)
*/
#include <bits/stdc++.h>
using namespace std;
ifstream fin("cuplaj.in");
ofstream fout("cuplaj.out");
int n,m,k;
vector< vector<int > > edges;
int cap[20005][20005];
vector<int> arb;
vector<int> vis;
int maxFlow;
bool bfs(){
fill(arb.begin(), arb.end(),0);
fill(vis.begin(), vis.end(),0);
arb[0] = 0;
vis[0] = 1;
queue<int> q;
q.push(0);
while(!q.empty()){
int curr = q.front();
q.pop();
if(curr == n+m+1)
return true;
for(int i = 0; i < edges[curr].size(); ++i){
if(vis[edges[curr][i]] == 0 && cap[curr][edges[curr][i]] > 0){
arb[edges[curr][i]] = curr;
vis[edges[curr][i]] = 1;
q.push(edges[curr][i]);
}
}
}
return false;
}
int main(){
fin >> n >> m >> k;
edges.resize(n+m+2);
arb.resize(n+m+2);
vis.resize(n+m+2);
int a,b,c;
for(int i = 1; i <= n; ++i){
edges[i].push_back(0);
edges[0].push_back(i);
cap[0][i] = 1;
}
for(int i = n+1; i <= n+m; ++i){
edges[i].push_back(n+m+1);
edges[n+m+1].push_back(i);
cap[i][n+m+1] = 1;
}
for(int i = 0; i < k; ++i){
fin >> a >> b;
edges[a].push_back(n+b);
edges[n+b].push_back(a);
cap[a][n+b] = 1;
}
while(bfs()){
for(int i = 0; i < edges[n+m+1].size(); ++i){
if(vis[edges[n+m+1][i]] == 1){
int fl = INT_MAX;
arb[n+m+1] = edges[n+m+1][i];
for(int j = n+m+1; j != 0; j = arb[j]){
fl = min(fl, cap[arb[j]][j]);
}
if(fl != 0){
for(int j = n+m+1; j != 0; j = arb[j]){
cap[arb[j]][j] -= fl;
cap[j][arb[j]] += fl;
}
maxFlow += fl;
}
}
}
}
fout << maxFlow << '\n';
for(int i = 1; i <= n; ++i){
for(int j = 1; j < edges[i].size(); ++j){
if(cap[i][edges[i][j]] == 0){
fout << i << ' ' << edges[i][j] - n << '\n';
}
}
}
}