Pagini recente » Cod sursa (job #2328480) | Cod sursa (job #1790088) | Cod sursa (job #2315383) | Cod sursa (job #22028) | Cod sursa (job #2552629)
#include <bits/stdc++.h>
#define NMAX 20100
using namespace std;
ifstream f("cuplaj.in");
ofstream g("cuplaj.out");
vector <int> v[10100];
int viz[10100],M1[10100],M2[10100];
int cupleaza(int nod)
{
if(viz[nod]==1) return 0; /// deja a fost luata in considerare
/// deci daca deja a fost luata in considerare si M1[nod] e inca 0 => ca nu am cum sa o cuplez in acest caz
viz[nod]=1; /// o iau in considerare
for(int i=0;i<v[nod].size();i++)
{
int vecin=v[nod][i];
if(M2[vecin]==0) /// daca e liber, go for it, il pui si mergi mai departe, poate obtii vreo solutie buna (in cazul asta am gasit o bucata de pamant libera)
{
M2[vecin]=nod; /// ii atribui bucatii de pamant legiunea respectiva
M1[nod]=vecin; /// dar si invers, ii atribui legiunii, bucata de pamant respectiva
return 1;
}
}
/// in for-ul asta ajung daca nu am gasit nicio bucata libera de pamant
/// ce fac? iau o bucata existenta si incerc sa o eliberez fortat
for(int i=0;i<v[nod].size();i++)
{
int vecin=v[nod][i];
if(cupleaza(M2[vecin])) /// bucata de pamant vecin are deja o legiune. ma uit daca exista cumva vreo alta bucata de pamant libera pentru a cupla legiunea asta
/// adica pentru legiunea corespunzatoare bucatii de pamant vecin, intru inca o data in cupleaza si daca gasesc o alta bucata de pamant libera, in primul for o sa obtin return 1
{
/// daca am putut sa cuplez acea legiune cu alta bucata, atunci legiunea mea actuala o cuplez cu bucata asta
M2[vecin]=nod;
M1[nod]=vecin;
return 1;
}
}
/// daca pana acum nu am dat niciun return 1 => ca nu exsita niciun mod de a cupla legiunea nod :(
return 0;
}
int n,m,e,OK,legiuni,i,x,y;
int main()
{
f>>n>>m>>e;
for(i=1;i<=e;i++)
{
f>>x>>y;
v[x].push_back(y);
}
OK=1;
while(OK) /// fac cat timp pot sa ii atribui pamant unei legiuni
{
OK=0;
/// vine un general nou (sau vechi - adica vine iarasi) si refacem procedeul
/// ideea e ca relatiile de cuplare se pastreaza (la venirea unui general nou, ele eventual se schimba)
for(i=1;i<=n;i++)viz[i]=0; /// nu a fost luat in considerare de generalul actual
for(i=1;i<=n;i++)
{
if(M1[i]==0) /// daca momentan nu i-am dat leginuii nicio bucata de pamant
{
int ok=cupleaza(i);
if(ok==1) /// pot sa cuplez legiunea i
{
OK=1;
legiuni++;
}
}
}
}
g<<legiuni<<'\n';
for(i=1;i<=n;i++)
if(M1[i]!=0)g<<i<<" "<<M1[i]<<'\n';
return 0;
}