Pagini recente » Cod sursa (job #2164981) | Cod sursa (job #840576) | Cod sursa (job #700308) | Cod sursa (job #1970223) | Cod sursa (job #2961411)
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
ifstream fin("cuplaj.in");
ofstream fout("cuplaj.out");
int n, m, e, N;
//int cap[1001][1001];//capacitatea muchiilor
int viz[20001];
pair<int, int>tata[20001];//ca sa retin nodurile vizitate si tatal nodurilor pentru reconstruirea drumului
vector<vector<pair<pair<int, int>, int>>> lista(20001);//lista de muchii
int bfs(){//bfs pentru aflarea existentei drumului de crestere
queue<int> coada;
coada.push(0);
for(int i = 0; i <= N; i++){
tata[i] = {-1, -1};
viz[i] = 0;
}
viz[0]++;
while(coada.size()!=0){
int nod_cur = coada.front();
//cout<<nod_cur<<" "<<tata[nod_cur]<<" ";
if(nod_cur == N)//daca am ajuns la final inseamna ca am gasit un drum de crestere
return 1;
int cnt = 0;
for(int i = 0; i < lista[nod_cur].size(); i++){
int nod_vec = lista[nod_cur][i].first.first;
if(lista[nod_cur][i].first.second > 0 && viz[nod_vec] == 0){//daca am gasit un nod prin care nu am mai fost care mai are loc, trecem prin el
viz[nod_vec]++;
tata[nod_vec] = {nod_cur, cnt};
coada.push(nod_vec);
}
cnt++;
}
coada.pop();//scot din coada nodul prin care deja am trecut
}
return 0;//nu am gasit
}
int Edmonds_Karp(){
int max_flux = 0;//fluxul maixim
while(bfs()){//cat timp avem drum de crestere
cout<<endl;
for(int i = 0; i < lista[N].size(); i++){
int nod_cur = lista[N][i].first.first;
if(lista[nod_cur][lista[N][i].second].first.second > 0 && viz[nod_cur]){//daca este drum care a dus de la vecinul lui n la n care mai are capacitate
//si a fost vizitat in verificarea noastra, atunci reconstituim drumul parcurs
//vector<pair<int, int>> drum;//reconstituirea drumului
//drum.push_back(nod_cur, );
cout<<nod_cur<<" ";
int minim = 9999999;//bottleneckul nostru
tata[N] = {nod_cur, lista[N][i].second};
int drum = N;
while(tata[drum].first!=-1){
minim = min(minim, lista[tata[drum].first][tata[drum].second].first.second);
drum = tata[drum].first;
//cout<<nod_cur<<" "<<tata[nod_cur]<<endl;
//drum.push_back(nod_cur);
}
// for(int i = 0; i < drum.size(); i++)//vedem care este bottleneckul drumului
// if(i == 0){
// minim = min(minim, lista[drum[i]][lista[N][drum[i]].second].first.second);
// cout<<lista[N][drum[i]].second<<" "<<drum[i]<<endl;
// }
// else
// minim = min(minim, lista[drum[i]][lista[drum[i-1]][drum[i]].second].first.second);
max_flux += minim;//il adaugam la flux doarece e cea mai mare valoare pe care o putem trece prin acel drum
drum = N;
while(tata[drum].first!=-1){
lista[tata[drum].first][tata[drum].second].first.second -= minim;
lista[drum][lista[tata[drum].first][tata[drum].second].second].first.second += minim;
drum = tata[drum].first;
}
// for(int i = 0; i < drum.size(); i++){
// if(i == 0){
// lista[drum[i]][lista[N][drum[i]].second].first.second -= minim;//scadem cap de la muchia de crestere
// lista[N][lista[drum[i]][N].second].first.second +=minim;//dar crestem cap muchiei de intoarece
// }
// else{
// lista[drum[i]][lista[drum[i-1]][drum[i]].second].first.second -= minim;
// lista[drum[i-1]][lista[drum[i]][drum[i-1]].second].first.second += minim;
// }
//
// }
cout<<minim<<" ";
}
//return 0;
}
}
return max_flux;//fluxul maxim
}
int main()
{
fin>>n>>m>>e;
N = n + m + 1;
for(int i = 0; i < e; i++){
int u, v;
fin>>u>>v;
lista[u].push_back({{v+n ,1}, lista[v+n].size()});
lista[v+n].push_back({{u, 0}, lista[u].size()-1});
}
for(int i = 1; i <= n; i++){
lista[0].push_back({{i, 1}, lista[i].size()});
lista[i].push_back({{0, 0}, lista[0].size()-1});
}
for(int i = 1; i <= m; i++){
lista[i+n].push_back({{n+m+1, 1}, lista[N].size()});
lista[n+m+1].push_back({{i+n, 0}, lista[i+n].size()-1});
}
fout<<Edmonds_Karp()<<"\n";
for(int i = 1; i <= n; i++)
for(int j = 0; j <lista[i].size(); j++){
if(lista[i][j].first.second != 1 && lista[i][j].first.first != 0)
fout<<i<<" "<<lista[i][j].first.first - n<<"\n";
}
}