Pagini recente » Cod sursa (job #184313) | Cod sursa (job #598743) | Cod sursa (job #885845) | Cod sursa (job #2596912) | Cod sursa (job #2968698)
#include <stdio.h>
// represents no node, no edge, no value etc.
#define NONE (-1)
// the maximum dimensions of the graph
#define NMAX (10'000)
#define MMAX (10'000)
#define EMAX (100'000)
// the graph
struct
{
// the edges of the graph
struct
{
int v; // the node this edge leads to
int next; // the next edge
} edges[EMAX];
// the first edge of each node
int begin[NMAX];
// for each node in U, its pair in V
int l[NMAX];
// for each node in V, its pair in U
int r[MMAX];
// for each node in U, whether or not it was used in the current iteration
bool used[NMAX];
// the no. of nodes and no. of edges
int n, m, e;
// init the graph with _n nodes
void init(int _n, int _m)
{
n = _n; m = _m;
for(int u = 0; u < n; u++)
begin[u] = NONE;
// set the pairs
for(int u = 0; u < n; u++)
l[u] = NONE;
for(int u = 0; u < m; u++)
r[u] = NONE;
}
// adds an edge from u to v
void add_edge(int u, int v)
{
edges[e] = { v, begin[u] };
begin[u] = e++;
}
// DFS from u to find the augmenting paths and add them to the maximal matching
bool dfs(int u)
{
// if u is used, return false
if(used[u])
return false;
// mark u as used
used[u] = true;
// go through the neighbours of u
for(int i = begin[u]; i != NONE; i = edges[i].next)
{
int v = edges[i].v;
// if the neighbour isn't in use, link it to u
if(r[v] == NONE)
{
l[u] = v;
r[v] = u;
return true;
}
}
// if this is reached, then all neighbours of u are in use, so try to reroute
for(int i = begin[u]; i != NONE; i = edges[i].next)
{
int v = edges[i].v;
// if we can reroute, do it
if(dfs(r[v]))
{
l[u] = v;
r[v] = u;
return true;
}
}
// if this is reached, then u can't be connected
return false;
}
} graph;
int main()
{
// open the files
freopen("cuplaj.in", "r", stdin);
freopen("cuplaj.out", "w", stdout);
// read the graph
int n, m, e;
scanf("%d %d %d", &n, &m, &e);
// init the graph
graph.init(n, m);
// read the edges
for(int i = 0; i < e; i++)
{
int u, v;
scanf("%d %d", &u, &v);
u--; v--;
graph.add_edge(u, v);
}
// reroute until not possible anymore
bool done;
do
{
// reset done and used
done = true;
for(int u = 0; u < n; u++)
graph.used[u] = false;
// go through the free nodes in U and try to match them
for(int u = 0; u < n; u++)
if(graph.l[u] == NONE)
done = (done && !graph.dfs(u));
} while (!done);
// count the cardinality
int cardinality = 0;
for(int u = 0; u < n; u++)
if(graph.l[u] != NONE)
cardinality++;
// print the cardinality
printf("%d\n", cardinality);
// print the set
for(int u = 0; u < n; u++)
if(graph.l[u] != NONE)
printf("%d %d\n", u + 1, graph.l[u] + 1);
// exit
return 0;
}