Pagini recente » Cod sursa (job #1745459) | Cod sursa (job #2774048) | Cod sursa (job #1880575) | Cod sursa (job #1177227) | Cod sursa (job #1051460)
#include <fstream>
#include <vector>
#include <string>
#include <sstream>
using namespace std;
class Digraph
{
private:
const int V;
int E;
vector< vector <int> >* adj;
public:
// CONSTRUCTORS
Digraph(int _V) : V(_V)
{
if (V < 0) throw 101; // number of vertices must be nonnegative
E = 0;
adj = new vector< vector<int> >(V);
for (int v = 0; v < V; ++v)
{
(*adj)[v] = vector<int>();
}
}
Digraph(Digraph* _G) : V(_G -> vertices())
{
// TO- DO: deep copy
}
// SET'S, MOD'S, etc
void add_edge(int v1, int v2)
{
// should also check for duplicate edges
// but there's not need for that
E ++;
(*adj)[v1].push_back(v2);
}
// GET'S
int vertices()
{
return V;
}
int edges()
{
return E;
}
vector<int>* adjacent(int _v)
{
if (_v < 0 || _v >= V) throw 101;
return &((*adj)[_v]);
}
// DEBUG
string toString()
{
stringstream ss;
ss << V << " vertices, " << E << " edges\n";
for (int v = 0; v < V; ++v)
{
ss << v << ": ";
int adj_v = (int)(*adj)[v].size();
for (int i = 0; i < adj_v; ++i)
{
ss << (*adj)[v][i] << " ";
}
ss << "\n";
}
return ss.str();
}
};
class MaximumMatching
{
private:
Digraph* graph;
vector<int>* left_to_right;
vector<int>* right_to_left;
vector<bool>* used;
int sz;
bool pairup(int v)
{
if ((*used)[v])
{
return false;
}
(*used)[v] = true;
vector<int>* adj_v = graph -> adjacent(v);
int adj_v_size = (int)adj_v -> size();
for (int i = 0; i < adj_v_size; ++i)
{
int u = (*adj_v)[i];
if (right_to_left -> at(u) == 0)
{
(*left_to_right)[v] = u;
(*right_to_left)[u] = v;
return true;
}
}
for (int i = 0; i < adj_v_size; ++i)
{
int u = (*adj_v)[i];
if (pairup(right_to_left -> at(u)))
{
(*left_to_right)[v] = u;
(*right_to_left)[u] = v;
return true;
}
}
return false;
}
void make_matching()
{
bool there_is_something_to_do = true;
while (there_is_something_to_do)
{
there_is_something_to_do = false;
for (int i = 0; i < used -> size(); ++i)
{
(*used)[i] = false;
}
for (int i = 1; i < graph -> vertices(); ++i)
{
if (left_to_right -> at(i) == 0)
{
there_is_something_to_do = pairup(i) || there_is_something_to_do;
}
}
}
}
void make_size()
{
sz = 0;
for (int i = 0; i < left_to_right -> size(); ++i)
{
sz += left_to_right -> at(i) != 0;
}
}
public:
MaximumMatching(Digraph* _graph, int left_vertices_n, int right_vertices_n)
{
graph = _graph;
used = new vector<bool>(graph -> vertices() + 10);
left_to_right = new vector<int>(left_vertices_n + 10);
right_to_left = new vector<int>(right_vertices_n + 10);
make_matching();
make_size();
}
vector<int>* left()
{
return left_to_right;
}
vector<int>* right()
{
return right_to_left;
}
int size()
{
return sz;
}
};
int main(int argc, const char * argv[])
{
ifstream fin("cuplaj.in");
ofstream fout("cuplaj.out");
int N, M, E;
fin >> N >> M >> E;
Digraph* graph = new Digraph(N + 1);
for (int i = 0; i < E; ++i)
{
int a, b;
fin >> a >> b;
graph -> add_edge(a, b);
}
MaximumMatching* matching = new MaximumMatching(graph, N, M);
vector<int>* left = matching -> left();
int size = matching -> size();
fout << size << "\n";
for (int i = 0; i < left -> size(); ++i)
{
if (left -> at(i) != 0)
{
fout << i << " " << left -> at(i) << "\n";
}
}
fin.close();
fout.close();
return 0;
}