Pagini recente » Cod sursa (job #1239850) | Istoria paginii runda/oji_sim2 | Cod sursa (job #2679180) | Cod sursa (job #880004) | Cod sursa (job #998895)
Cod sursa(job #998895)
#include <cstdio>
#include <algorithm>
#include <vector>
#include <bitset>
using namespace std;
int st[10005],dr[10005];
bitset<10005>used;
vector<int>lv[10005];
//lv[i] se va construi pt. i din stinga shi va contzine lista vecinilor
//din dreapta
int n,m,e,x,y;
int caut_drum(const int i)
{
used[i]=1;
vector<int>::iterator j;
//luam toat muchiile i,*j
for(j=lv[i].begin();j!=lv[i].end();++j)
//vedem daca muchia (i,*j) se termina in *j necuplat
if(st[*j]==0)//daca da, inseamna ca drumul e gasit, intoarcem 1 shi
//folosim muchia in cuplaj
{
dr[i]=*j;
st[*j]=i;
return 1;
}
else//deci *j e deja cuplat cu altcineva
//am ales muchia (i,*j). Ideea e ca *j sa fie cuplat insa NU la loc cu i,
//cu alte cuvinte muchia (i,*j) sa nu faca parte din cuplaj
if(st[*j]!=i&&!used[st[*j]])
{
//in cazul asta e ok, pot sa continui back-ul mai departe din st[*j]
int inou=st[*j];
if(caut_drum(inou))
{
dr[i]=*j;
st[*j]=i;
return 1;
}
}
return 0;
}
int main()
{
FILE *f=fopen("cuplaj.in","r");
fscanf(f,"%d%d%d",&n,&m,&e);
int i,modif;
for(i=1;i<=e;i++)
{
fscanf(f,"%d%d",&x,&y);
lv[x].push_back(y);
if(dr[x]==0&&st[y]==0)
{
dr[x]=y;st[y]=x;
}
}
do
{
modif=0;//asta e un flag care-mi indica daca am modif. la parcurgerea
//curenta
for(i=1;i<=n;i++)used[i]=0;
//vectorul used imi retzine nodurile din stinga atinse de vreun drum
//alternant
for(i=1;i<=n;i++)
if(!used[i]&&dr[i]==0)//caut drum cauta cu back un drum, il shi opereaza
if(caut_drum(i))//shi daca-l gaseshte intoarce 1
modif=1;
}while(modif);
FILE *fout=fopen("cuplaj.out","w");
int nc=0;
for(i=1;i<=n;i++)if(dr[i])nc++;
fprintf(fout,"%d\n",nc);
for(i=1;i<=n;i++)
if(dr[i])
fprintf(fout,"%d %d\n",i,dr[i]);
return 0;
}