Pagini recente » Cod sursa (job #2437656) | Cod sursa (job #106128) | Cod sursa (job #2948913) | Cod sursa (job #2849073) | Cod sursa (job #2958438)
#include <iostream>
#include <fstream>
#include <math.h>
#include <queue>
#define MAX 110000
using namespace std;
ifstream in("cuplaj.in");
ofstream out("cuplaj.out");
/*
Idee: creez reteaua de transport asociata grafului si calculez fluxul maxim (= cuplajul maxim) -> Edmonds-Karp
Afisez muchiile pe care fluxul final e 1
*/
int n, m, e;
pair<int, int> muchie[10001][10001]; //fluxul si capacitatile pe muchii
vector<int> tata; //vectorul de tati
vector<int> l[10001]; //lista muchiilor
vector<int> cc; //capacitatea ramasa la mom. curent
int bfs(int s, int t)
{
queue <int> q;
//la fiecare parcurgere modificam vectorul de tati si capacitatile ramase
for(int i=0; i<=n+m+1; i++)
{
tata[i] = -1;
cc[i] = 0;
}
cc[s] = MAX; //capacitatea ramasa in sursa e maxima
q.push(s);
while(!q.empty())
{
int nod = q.front();
q.pop();
for(int i=0; i<l[nod].size(); i++)
{
int nodNou = l[nod][i];
if(tata[nodNou] == -1) //daca nodul curent nu a fost parcurs
{
//actualizez capaciatea curenta cu cea minima pe lant
if(muchie[nod][nodNou].second - muchie[nod][nodNou].first > 0)
{
tata[nodNou] = nod;
cc[nodNou] = min(cc[nod], muchie[nod][nodNou].second - muchie[nod][nodNou].first);
if(nodNou == t)
return cc[t];
q.push(nodNou);
}
}
}
}
return 0;
}
int fluxMax(int s, int t)
{
int rez = 0;
int flux = bfs(s, t);
while(flux != 0)
{
rez += flux;
int nod = t;
while(nod != s) //revizuiesc fluxul
{
int t = tata[nod];
muchie[t][nod].first += flux;
muchie[nod][t].first -= flux;
nod = t;
}
flux = bfs(s, t);
}
return rez;
}
int main()
{
in>>n>>m>>e;
tata.resize(n+m+2);
cc.resize(n+m+2);
int x, y;
for(int i=1; i<=e; i++)
{
cin>>x>>y;
y = y + n; //adaug n la y ca sa il diferentiez de x
muchie[x][y].second = 1;
muchie[x][y].first = 0;
muchie[0][x].second = 1;
muchie[y][n+m+1].second = 1;
l[x].push_back(y);
l[y].push_back(x);
l[0].push_back(x); //0 e nodul de start, se leaga de toate nodurile x
l[x].push_back(0);
l[y].push_back(n+m+1); //y se leaga de nodul de oprire, adica n+m+1
l[n+m+1].push_back(y);
}
int f = fluxMax(0, n+m+1);
out<<f<<"\n";
for(int i=1; i<=n; i++)
{
for(int j=0; j<l[i].size(); j++)
{
int nod = l[i][j];
if(muchie[i][nod].first == 1)
out<<i<<" "<<nod-n<<" "<<"\n";
}
}
return 0;
}