Pagini recente » Cod sursa (job #2603071) | Cod sursa (job #780545) | Cod sursa (job #2898360) | Cod sursa (job #1089158) | Cod sursa (job #2962646)
//Link solutie: https://www.infoarena.ro/job_detail/2961044?action=view-source
//Explicatie: Pentru a determina cuplajul maxim intr-un graf bipartit trebuie sa
//determinam fluxul maxim intr-o retea de transport asociata grafului. Astfel, alegem
//nodul 0 ca fiind nodul sursa, si nodul n+m+1 ca fiind nodul terminal. Adaugam arce de la
//sursa la prima bipartitie a grafului, si alte arce de la a doua bipartitie a grafului la nodul terminal.
//Transformam muchiile grafului in arce de la prima bipartitie la a doua, si asociem fiecarui
//arc capacitatea 1. Apoi aplicam flux. Verificam apoi care muchii din graful bipartit
//initial sunt saturate, le numaram si le afisam.
//Complexitate:O(n*m^2)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("cuplaj.in");
ofstream fout("cuplaj.out");
int n,m,e,graf[2001][2001],a,b,rgraf[2001][2001];
bool vizitat[2001];
vector<int> vecn;
//functie pentru sortat muchiile
bool functie_sort(pair<int,int>a, pair<int, int> b)
{
return a.second<b.second;
}
//bfs pentru determinarea drumurilor de lungime minima de la sursa la nodurile legate
//direct de nodul terminal
bool bfs( int tata[], int n)
{
for(int i=0;i<=n+m+1;i++)
vizitat[i] = false;
queue<int> q;
q.push(0);
vizitat[0] = true;
tata[0] = -1;
while(!q.empty())
{
int u = q.front();
q.pop();
for(int i = 0; i<=n+m+1;i++)
{
if(vizitat[i] == false && rgraf[u][i] > 0)
{
if(i == n+m+1)
{
return true;
}
q.push(i);
tata[i] = u;
vizitat[i] = true;
}
}
}
return false;
}
int main()
{
fin>>n>>m>>e;
for(int i=0;i<e;i++)
{
fin>>a>>b;
graf[a][n+b] = 1;
}
for(int i=1;i<=n;i++)
{
graf[0][i] = 1;
}
for(int i=1;i<=m;i++)
{
graf[n+i][n+m+1] = 1;
}
for(int i=n+1;i<=m+n;i++)
{
if(graf[i][n+m+1] >0)
vecn.push_back(i);
}
for(int i=0;i<=n+m+1;i++)
for(int j=0;j<=n+m+1;j++)
{
rgraf[i][j] = graf[i][j];
}
int tata[n+m+2];
while(bfs( tata, n))
{
for(int vec:vecn) {
if(vizitat[vec] == true && rgraf[vec][n+m+1] > 0) {
tata[n + m + 1] = vec;
int capacitate_drum = INT_MAX;
for (int i = n + m + 1; i != 0; i = tata[i]) {
int u = tata[i];
capacitate_drum = min(capacitate_drum, rgraf[u][i]);
}
for (int i = n + m + 1; i != 0; i = tata[i]) {
int u = tata[i];
rgraf[u][i] -= capacitate_drum;
rgraf[i][u] += capacitate_drum;
}
}
}
}
int nr_muchii=0;
vector<pair<int,int>> muchii;
for(int i=n+1;i<=n+m;i++)
{
for(int j=1;j<=n;j++)
{
if(rgraf[i][j] == 1)
{
nr_muchii++;
muchii.push_back(make_pair(i-n,j));
}
}
}
sort(muchii.begin(),muchii.end(), functie_sort);
fout<<nr_muchii<<endl;
for(pair<int,int> i : muchii)
{
fout<<i.second<<" "<<i.first<<endl;
}
return 0;
}