Pagini recente » Cod sursa (job #2743221) | Cod sursa (job #1303780) | Cod sursa (job #2553180) | Cod sursa (job #1088088) | Cod sursa (job #3331824)
// #include <iostream> // Librăria pentru fluxurile standard de intrare/ieșire
// #include <vector> // Librăria pentru vectori (liste dinamice)
// #include <queue> // Librăria pentru structura de date de tip coadă (folosită la BFS)
// #include <fstream> // Librăria pentru lucrul cu fișiere
// using namespace std; // Permite utilizarea funcțiilor standard fără prefixul std::
// const int MAXN = 10005; // Definim dimensiunea maximă pentru noduri conform restricțiilor
// const int INF = 1e9; // Definim o valoare foarte mare pentru distanțe (infinit)
// ifstream fin("cuplaj.in"); // Deschidem fișierul de intrare
// ofstream fout("cuplaj.out"); // Deschidem fișierul de ieșire
// vector<int> adj[MAXN]; // Lista de adiacență pentru a stoca muchiile dintre mulțimile A și B
// int perecheA[MAXN]; // perecheA[u] stochează nodul din B cu care este cuplat u din A
// int perecheB[MAXN]; // perecheB[v] stochează nodul din A cu care este cuplat v din B
// int dist[MAXN]; // Stochează nivelul (stratul) fiecărui nod calculat de BFS
// int n, m, e; // n - noduri în A, m - noduri în B, e - numărul de muchii
// // Funcția BFS: Împarte graful în straturi pentru a găsi cele mai scurte drumuri de creștere
// bool bfs() {
// queue<int> q; // Creăm o coadă pentru parcurgerea în lățime
// for (int i = 1; i <= n; i++) { // Parcurgem toate nodurile din mulțimea A
// if (perecheA[i] == 0) { // Dacă nodul i este liber (necuplat)
// dist[i] = 0; // Începe un nou drum de creștere (nivelul 0)
// q.push(i); // Îl adăugăm în coadă pentru procesare
// } else {
// dist[i] = INF; // Dacă e deja cuplat, îl marcam cu infinit (nevizitat)
// }
// }
// dist[0] = INF; // Nodul 0 este un nod virtual care reprezintă "capătul" unui drum de creștere
// while (!q.empty()) { // Cât timp mai avem noduri în coadă
// int u = q.front(); // Luăm primul nod din coadă
// q.pop(); // Îl eliminăm din coadă
// if (dist[u] < dist[0]) { // Dacă nu am depășit nivelul primului drum de creștere găsit
// for (int v : adj[u]) { // Analizăm toți vecinii nodului u din mulțimea B
// // Verificăm dacă partenerul lui v (care e în A) nu a fost vizitat
// if (dist[perecheB[v]] == INF) {
// dist[perecheB[v]] = dist[u] + 1; // Setăm stratul următor
// q.push(perecheB[v]); // Adăugăm partenerul în coadă
// }
// }
// }
// }
// // Returnează true dacă am reușit să ajungem la nodul virtual 0 (un nod liber din B)
// return (dist[0] != INF);
// }
// // Funcția DFS: Caută drumuri de creștere pe straturile definite de BFS
// bool dfs(int u) {
// if (u != 0) { // Dacă nodul curent nu este nodul virtual de final
// for (int v : adj[u]) { // Parcurgem vecinii nodului u
// // Verificăm dacă vecinul face parte din stratul imediat următor
// if (dist[perecheB[v]] == dist[u] + 1) {
// if (dfs(perecheB[v])) { // Încercăm să găsim un drum de creștere recursiv
// perecheB[v] = u; // Dacă s-a găsit, actualizăm cuplajul pentru v
// perecheA[u] = v; // Actualizăm cuplajul pentru u
// return true; // Confirmăm că drumul a fost găsit
// }
// }
// }
// dist[u] = INF; // Dacă nu există drum prin u, îl marcăm pentru a nu-l mai vizita
// return false; // Nu am găsit drum de creștere prin acest nod
// }
// return true; // Am ajuns la nodul virtual 0, drumul de creștere este complet
// }
// int main() {
// if (!(fin >> n >> m >> e)) return 0; // Citim dimensiunile și verificăm dacă s-a reușit
// for (int i = 0; i < e; i++) { // Citim cele e muchii ale grafului
// int u, v; // Variabile pentru nodurile ce formează muchia
// fin >> u >> v; // Citim nodul u din A și nodul v din B
// adj[u].push_back(v); // Adăugăm v în lista de adiacență a lui u
// }
// int cuplaj_maxim = 0; // Variabilă pentru a număra câte perechi am format
// // Rulăm algoritmul în faze: BFS construiește straturi, DFS caută drumuri în ele
// while (bfs()) { // Cât timp BFS găsește drumuri de creștere posibile
// for (int i = 1; i <= n; i++) { // Pentru fiecare nod din mulțimea A
// // Dacă nodul este liber și DFS reușește să îi găsească o pereche
// if (perecheA[i] == 0 && dfs(i)) {
// cuplaj_maxim++; // Incrementăm mărimea totală a cuplajului
// }
// }
// }
// fout << cuplaj_maxim << "\n"; // Afișăm numărul maxim de perechi formate
// for (int i = 1; i <= n; i++) { // Parcurgem nodurile din prima mulțime
// if (perecheA[i] != 0) { // Dacă nodul i a fost cuplat
// fout << i << " " << perecheA[i] << "\n"; // Afișăm perechea (A, B)
// }
// }
// return 0; // Finalizăm programul
// }
// Copilot Rules:
// RULE: There shouldnt be any spaces in the code, except after commas.
// RULE: All variables in main should be declared globally, and can be used before they are defined.
// RULE: All open curly braces should be placed on the same line as the function or control structure they belong to, not on the line after.
#include <bits/stdc++.h>
#define N 10010
using namespace std;
ifstream fin("cuplaj.in"); //strudel
ofstream fout("cuplaj.out"); //cuplaj
int n,m,e,i,x,y,cnt,inf=1e9;
vector<int> v[N];
int pda[N],pdb[N],lvl[N];
queue<int> q;
bool bfs(){
while(!q.empty()) q.pop();
for(i=1;i<=n;i++){
if(pdb[i]==0) lvl[i]=0,q.push(i);
else lvl[i]=inf;
}
lvl[0]=inf;
while(!q.empty()){
int u=q.front();
q.pop();
if(lvl[u]<lvl[0])
for(auto vec:v[u]){
if(lvl[pda[vec]]==inf){
lvl[pda[vec]]=lvl[u]+1;
q.push(pda[vec]);
}
}
}
return lvl[0]!=inf;
}
bool dfs(int nod){
if(nod==0) return 1;
for(auto vec:v[nod]){
if(lvl[pda[vec]]==lvl[nod]+1&&dfs(pda[vec])==1){
pda[vec]=nod,pdb[nod]=vec;
return 1;
}
}
lvl[nod]=inf;
return 0;
}
int main()
{
fin>>n>>m>>e;
for(i=1;i<=e;i++){
fin>>x>>y;
v[x].push_back(y);
}
while(bfs()==1){
for(i=1;i<=n;i++){
if(pdb[i]==0&&dfs(i)==1){
cnt++;
}
}
}
fout<<cnt<<'\n';
for(i=1;i<=n;i++)
if(pdb[i]!=0) fout<<i<<" "<<pdb[i]<<'\n';
return 0;
}