Pagini recente » Cod sursa (job #2801234) | Cod sursa (job #1511786) | Cod sursa (job #2568692) | Cod sursa (job #405435) | Cod sursa (job #2961042)
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <cstring>
#include <fstream>
using namespace std;
ifstream in("cuplaj.in");
ofstream out("cuplaj.out");
vector<int> l[20001];
int viz[20001], gr1[20001], gr2[20001] ;
int n, m;
int matching(int val)
{
if(viz[val])
return 0;
viz[val] = 1;
for(int i = 0; i < l[val].size(); i++)
if(!gr2[l[val][i]])
{
gr1[val] = l[val][i];
gr2[l[val][i]] = val;
return 1;
}
for(int i = 0; i < l[val].size(); i++)
if(matching(gr2[l[val][i]]))
{
gr1[val] = l[val][i];
gr2[l[val][i]] = val;
return 1;
}
return 0;
}
int main()
{
int n, m, e, st, fin, ok = 1, match = 0;
in>>n>>m>>e;
for(int i = 1; i <= e; i++)
{
in>>st>>fin;
l[st].push_back(fin);
}
while(ok)
{
ok = 0;
memset(viz, 0, sizeof(viz));
for(int i = 1; i <= n; i++)
if(!gr1[i])
ok |= matching(i);
}
for(int i = 1; i <= n; i++)
if(gr1[i])
match += 1;
out<<match<<"\n";
for(int i = 1; i <= n; i++)
if(gr1[i])
out<<i<<" "<<gr1[i]<<"\n";
return 0;
}
/*
///flow_sent -> fluxul trimis pe o muchie, capacity -> capacitatea muchiei,
int flow_sent[1005][1005], capacity[1005][1005], minim[1005];
///l -> vecorul care retine graful + graful rezidual
vector<int> l[20001];
///n -> noduri, m -> muchii
int n, m;
///vectorul de parinti
int tata[1005] = {0};
int bfs(int src, int dest)
{
queue<int> q;
///rescriem valorile din vectorul de tati si cel de distante
memset(tata, -1, sizeof(tata));
memset(minim, 0, sizeof(minim));
q.push(src);
tata[src] = -2;
minim[src] = 99999;
///BFS clasic
while(!q.empty())
{
int u = q.front();
q.pop();
for(int i = 0; i < l[u].size(); i++)
{
int v = l[u][i];
///inseamna ca nu e vizitat
if(capacity[u][v] > flow_sent[u][v] && tata[v] == -1)
{
///updatam vectorul de tati pentru a avea drumul
tata[v] = u;
minim[v] = min(minim[u], capacity[u][v] - flow_sent[u][v]);
///iesim cu 1 daca am ajuns la nodul n(cel final)
if(v == dest)
return minim[u];
q.push(v);
}
}
}
return 0;
}
///pentru a optimiza programul efectuam algoritmul lui Edmonds Karp atata timp
///cat prin parcurerea BFS putem ajunge din nodul 1 in nodul n, ceea ce inseamna
///ca estista un drum pe care fluxul rezidual sa fie minim si mai am capacitate
///disponibila pe muchii pentru a mari fluxul
int max_flow(int src, int dest)
{
///maxim -> fluxul maxim, flow -> fluxul minim rezidual gasit dupa parcurgerea BFS
///u -> nodul curent, v -> vecinul acestuia
int maxim = 0, flow, u, v;
///cat timp prin parcurgerea BFS ajung din nodul 1 in nodul n
while(true)
{
flow = bfs(src, dest);
if(flow == 0)
break;
maxim += flow;
u = dest;
while(u != src)
{
v = tata[u];
flow_sent[v][u] += flow;
flow_sent[u][v] -= flow;
u = v;
}
}
return maxim;
}
int main()
{
int n, m, e, dest, src = 0, st, fin;
in>>n>>m>>e;
dest = n + m + 1;
for(int i = 1; i <= n; i++)
{
l[0].push_back(i);
l[i].push_back(0);
capacity[0][i] = 1;
}
for(int i = 1; i <= m; i++)
{
l[dest].push_back(n+i);
l[n+i].push_back(dest);
capacity[n+i][dest] = 1;
}
for(int i = 1; i <= e; i++)
{
in>>st>>fin;
l[st].push_back(fin+n);
l[fin+n].push_back(st);
capacity[st][fin+n] = 1;
}
out<<max_flow(src, dest)<<"\n";
for(int i = 1; i <= n; i++)
for(int j = n + 1; j <= n + m; j++)
if(flow_sent[i][j])
out<<i<<" "<<j-n<<"\n";
return 0;
}*/