Pagini recente » Cod sursa (job #316393) | Cod sursa (job #3188387) | Cod sursa (job #2518278) | Cod sursa (job #2923026) | Cod sursa (job #2971804)
/*
Cuplaj maxim in graf bipartit
Se dă un graf neorientat bipartit G = (V = (L, R), E). Un cuplaj în G este o submulţime de muchii M astfel încât pentru toate vârfurile v din V, există cel mult o muchie în M incidentă în v. Un cuplaj maxim este un cuplaj de cardinalitate maximă.
Cerinţa
Dându-se un graf neorientat bipartit G să se determine un cuplaj maxim.
Date de intrare
Fişierul de intrare cuplaj.in conţine pe prima linie trei numere naturale N, M şi E, unde N reprezintă cardinalul mulţimii L iar M cardinalul mulţimii R. Pe următoarele E linii se vor afla câte două numere naturale, separate între ele printr-un spaţiu, u şi v, cu semnificaţia că există muchie de la nodul u din L la nodul v din R.
Date de ieşire
În fişierul de ieşire cuplaj.out veţi afişa pe prima linie un singur număr reprezentând cuplajul maxim. Pe fiecare din următoarele linii veţi afişa câte două numere x şi y, separate între ele prin spaţiu, cu semnificaţia că nodul x din L a fost cuplat cu nodul y din R.
Restricţii
1 ≤ N, M ≤ 10 000
0 ≤ E ≤ minim(100 000, N * M)
Pentru 20% dintre teste: 1 ≤ N ≤ 100, 1 ≤ M ≤ 20
Pentru 50% dintre teste: 1 ≤ (N + M) * E ≤ 5 * 106
Pentru determinarea corectă a cuplajului maxim se va acorda 40% din punctaj şi încă 60% dacă s-a determinat o submulţime M validă.
IN:
5 4 9
1 1
1 2
2 1
2 2
2 3
3 2
4 2
5 2
5 4
OUT:
4
1 1
2 3
3 2
5 4
*/
/// Kuhn's Algorithm
#include <bits/stdc++.h>
#define ll long long
#define pb push_back
#define pf push_front
#define MOD 1000000007
#define MAX 10005
using namespace std;
vector < int > v[MAX];
int p[MAX];
bool viz[MAX];
bool dfs(int nod);
int main()
{
ifstream cin("cuplaj.in");
ofstream cout("cuplaj.out");
int l, r, m, x, y, i, nr = 0;
cin >> l >> r >> m;
for(i = 1; i <= m; i++)
{
cin >> x >> y;
v[x].pb(y);
}
for(i = 1; i <= r; i++) p[i] = -1;
for(x = 1; x <= l; x++)
{
for(i = 1; i <= l; i++) viz[i] = 0;
if(dfs(x) == 1) nr++;
}
cout << nr << '\n';
for(i = 1; i <= r; i++) if(p[i] != -1) cout << p[i] << ' ' << i << '\n';
return 0;
}
bool dfs(int nod)
{
viz[nod] = 1;
for (int x: v[nod]) if(p[x] == -1 || (viz[p[x]] == 0 && dfs(p[x]) == 1))
{
p[x] = nod;
return 1;
}
return 0;
}