#include <vector>
#include <cassert>
#include <iostream>
typedef std::vector<bool> matrix_row;
typedef std::vector<matrix_row> matrix;
matrix adj =
{
{ 1, 1, 1, 0 },
{ 1, 0, 0, 1 },
{ 1, 0, 0, 1 },
{ 0, 1, 1, 0 }
};
matrix adjacency_to_incidence(const matrix &adj)
{
int cols = adj.size();
assert(cols > 0);
int rows = adj[0].size();
assert(rows > 0);
assert(rows == cols);
int edge = 0;
matrix incidence;
for (int col = 0; col < cols; ++col) {
for (int row = 0; row <= col; ++row) {
if (adj[col][row]) {
incidence.push_back(matrix_row(cols, 0));
incidence[edge][row] = incidence[edge][col] = 1;
++edge;
}
}
}
return incidence;
}
matrix incidence_to_adjacency(const matrix &inc)
{
int edges = inc.size();
assert(edges > 0);
int vertices = inc[0].size();
assert(vertices > 0);
matrix adjacency(vertices, matrix_row(vertices, 0));
for (int edge = 0; edge < edges; ++edge) {
int a = -1, b = -1, vertex = 0;
for (; vertex < vertices && a == -1; ++vertex) {
if (inc[edge][vertex]) a = vertex;
}
for (; vertex < vertices && b == -1; ++vertex) {
if (inc[edge][vertex]) b = vertex;
}
if (b == -1) b = a;
adjacency[a][b] = adjacency[b][a] = 1;
}
return adjacency;
}
void print_matrix(const matrix &m)
{
int cols = m.size();
if (cols == 0) return;
int rows = m[0].size();
if (rows == 0) return;
for (int c = 0; c < cols; ++c) {
for (int r = 0; r < rows; ++r) {
std::cout << m[c][r] << " ";
}
std::cout << std::endl;
}
std::cout << std::endl;
}
int main()
{
matrix incidence = adjacency_to_incidence(adj);
print_matrix(incidence);
matrix adjacency = incidence_to_adjacency(incidence);
print_matrix(adjacency);
return 0;
}
I2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPGNhc3NlcnQ+CiNpbmNsdWRlIDxpb3N0cmVhbT4KCnR5cGVkZWYgc3RkOjp2ZWN0b3I8Ym9vbD4gbWF0cml4X3JvdzsKdHlwZWRlZiBzdGQ6OnZlY3RvcjxtYXRyaXhfcm93PiBtYXRyaXg7CgptYXRyaXggYWRqID0gCnsKICAgIHsgMSwgMSwgMSwgMCB9LAogICAgeyAxLCAwLCAwLCAxIH0sCiAgICB7IDEsIDAsIDAsIDEgfSwKICAgIHsgMCwgMSwgMSwgMCB9Cn07CgptYXRyaXggYWRqYWNlbmN5X3RvX2luY2lkZW5jZShjb25zdCBtYXRyaXggJmFkaikKewogICAgaW50IGNvbHMgPSBhZGouc2l6ZSgpOwogICAgYXNzZXJ0KGNvbHMgPiAwKTsKCiAgICBpbnQgcm93cyA9IGFkalswXS5zaXplKCk7CiAgICBhc3NlcnQocm93cyA+IDApOwoKICAgIGFzc2VydChyb3dzID09IGNvbHMpOwoKICAgIGludCBlZGdlID0gMDsKICAgIG1hdHJpeCBpbmNpZGVuY2U7CgogICAgZm9yIChpbnQgY29sID0gMDsgY29sIDwgY29sczsgKytjb2wpIHsKICAgICAgICBmb3IgKGludCByb3cgPSAwOyByb3cgPD0gY29sOyArK3JvdykgewogICAgICAgICAgICBpZiAoYWRqW2NvbF1bcm93XSkgewogICAgICAgICAgICAgICAgaW5jaWRlbmNlLnB1c2hfYmFjayhtYXRyaXhfcm93KGNvbHMsIDApKTsKICAgICAgICAgICAgICAgIGluY2lkZW5jZVtlZGdlXVtyb3ddID0gaW5jaWRlbmNlW2VkZ2VdW2NvbF0gPSAxOwogICAgICAgICAgICAgICAgKytlZGdlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBpbmNpZGVuY2U7Cn0KCm1hdHJpeCBpbmNpZGVuY2VfdG9fYWRqYWNlbmN5KGNvbnN0IG1hdHJpeCAmaW5jKQp7CiAgICBpbnQgZWRnZXMgPSBpbmMuc2l6ZSgpOwogICAgYXNzZXJ0KGVkZ2VzID4gMCk7CgogICAgaW50IHZlcnRpY2VzID0gaW5jWzBdLnNpemUoKTsKICAgIGFzc2VydCh2ZXJ0aWNlcyA+IDApOwoKICAgIG1hdHJpeCBhZGphY2VuY3kodmVydGljZXMsIG1hdHJpeF9yb3codmVydGljZXMsIDApKTsKCiAgICBmb3IgKGludCBlZGdlID0gMDsgZWRnZSA8IGVkZ2VzOyArK2VkZ2UpIHsKICAgICAgICBpbnQgYSA9IC0xLCBiID0gLTEsIHZlcnRleCA9IDA7CiAgICAgICAgZm9yICg7IHZlcnRleCA8IHZlcnRpY2VzICYmIGEgPT0gLTE7ICsrdmVydGV4KSB7CiAgICAgICAgICAgIGlmIChpbmNbZWRnZV1bdmVydGV4XSkgYSA9IHZlcnRleDsKICAgICAgICB9CiAgICAgICAgZm9yICg7IHZlcnRleCA8IHZlcnRpY2VzICYmIGIgPT0gLTE7ICsrdmVydGV4KSB7CiAgICAgICAgICAgIGlmIChpbmNbZWRnZV1bdmVydGV4XSkgYiA9IHZlcnRleDsKICAgICAgICB9CiAgICAgICAgaWYgKGIgPT0gLTEpIGIgPSBhOwogICAgICAgIGFkamFjZW5jeVthXVtiXSA9IGFkamFjZW5jeVtiXVthXSA9IDE7CiAgICB9CgogICAgcmV0dXJuIGFkamFjZW5jeTsKfQoKdm9pZCBwcmludF9tYXRyaXgoY29uc3QgbWF0cml4ICZtKQp7CiAgICBpbnQgY29scyA9IG0uc2l6ZSgpOwogICAgaWYgKGNvbHMgPT0gMCkgcmV0dXJuOwogICAgaW50IHJvd3MgPSBtWzBdLnNpemUoKTsKICAgIGlmIChyb3dzID09IDApIHJldHVybjsKCiAgICBmb3IgKGludCBjID0gMDsgYyA8IGNvbHM7ICsrYykgewogICAgICAgIGZvciAoaW50IHIgPSAwOyByIDwgcm93czsgKytyKSB7CiAgICAgICAgICAgIHN0ZDo6Y291dCA8PCBtW2NdW3JdIDw8ICIgIjsKICAgICAgICB9CiAgICAgICAgc3RkOjpjb3V0IDw8IHN0ZDo6ZW5kbDsKICAgIH0KICAgIHN0ZDo6Y291dCA8PCBzdGQ6OmVuZGw7Cn0KCmludCBtYWluKCkKewogICAgbWF0cml4IGluY2lkZW5jZSA9IGFkamFjZW5jeV90b19pbmNpZGVuY2UoYWRqKTsKICAgIHByaW50X21hdHJpeChpbmNpZGVuY2UpOwoKICAgIG1hdHJpeCBhZGphY2VuY3kgPSBpbmNpZGVuY2VfdG9fYWRqYWNlbmN5KGluY2lkZW5jZSk7CiAgICBwcmludF9tYXRyaXgoYWRqYWNlbmN5KTsKCiAgICByZXR1cm4gMDsKfQo=