Pagini recente » Cod sursa (job #2396534) | Cod sursa (job #2782110) | Cod sursa (job #2689088) | Cod sursa (job #2278494) | Cod sursa (job #2590454)
#define MAX_NM 10000
#define LFT ((byte) 'L')
#define RIG ((byte) 'R')
#include <fstream>
#include <set>
#include <queue>
#include <utility>
#include <vector>
using namespace std;
using byte = unsigned char;
ifstream fin("cuplaj.in");
ofstream fout("cuplaj.out");
int n, m, e;
set<int> L[MAX_NM + 1], R[MAX_NM + 1], Ramase;
// Noduri terminale.
queue<pair<int, byte>> Term;
vector<pair<int, int>> Rasp;
void Init();
void Cupleaza(int nodL, int nodR);
int main()
{
fin >> n >> m >> e;
for (int i = 0, u, v; i < e; ++i)
{
fin >> u >> v;
L[u].insert(v);
R[v].insert(u);
}
Init();
bool ok;
do
{
INCEPUT:
while (!Term.empty())
{
int nod = Term.front().first;
byte tip = Term.front().second;
Term.pop();
if (tip == LFT) { Ramase.erase(nod); }
auto& cont = (tip == LFT) ? L : R;
if (cont[nod].size() == 1)
{
int nodL = (tip == LFT) ? nod : (*cont[nod].begin());
int nodR = (tip == RIG) ? nod : (*cont[nod].begin());
Cupleaza(nodL, nodR);
}
}
ITERARE:
ok = false;
for (int nod : Ramase)
{
if (L[nod].size() != 0)
{
ok = true;
Cupleaza(nod, *L[nod].begin());
if (!Term.empty())
{
goto INCEPUT;
}
else
{
Ramase.erase(nod);
goto ITERARE;
}
}
}
}
while (ok);
fout << Rasp.size() << '\n';
for (size_t i = 0; i < Rasp.size(); ++i)
{
fout << Rasp[i].first << ' ' << Rasp[i].second << '\n';
}
fin.close();
fout.close();
return 0;
}
void Init()
{
for (int i = 1; i <= n; ++i)
{
if (L[i].size() == 1) { Term.emplace(i, LFT); }
else { Ramase.insert(i); }
}
for (int i = 1; i <= m; ++i)
{
if (R[i].size() == 1) { Term.emplace(i, RIG); }
}
}
void Cupleaza(int nodL, int nodR)
{
Rasp.emplace_back(nodL, nodR);
for (int vecin : L[nodL])
{
if (vecin != nodR)
{
R[vecin].erase(nodL);
if (R[vecin].size() == 1)
{
Term.emplace(vecin, RIG);
}
}
}
for (int vecin : R[nodR])
{
if (vecin != nodL)
{
L[vecin].erase(nodR);
if (L[vecin].size() == 1)
{
Term.emplace(vecin, LFT);
}
}
}
L[nodL].clear();
R[nodR].clear();
}