• count how many triangles can be formed inside the graph
  • undirected graph, and each triangle would be counted for three times, once per node.
  • $O(n^3)$
#include <iostream>
#include <vector>

// Reference: https://github.com/georgegito/vertexwise-triangle-counting/blob/master/src/v3/v3_seq.cpp
// allow for parallelism
auto bfs_tc(const std::vector<int>& rowPtr, const std::vector<int>& colIdx)
{
  int        numTriangles = 0;
  const auto numVertices  = rowPtr.size() - 1;
  // check if two nodes have an edge between them with binary search (require sorted colIdx)
  auto intersect = [&](int first, int second) -> bool {
    // std::find is O(N), assuming the iterator is a forward iterator
    // auto first_begin = colIdx.begin() + rowPtr[first];
    // auto first_end   = colIdx.begin() + rowPtr[first + 1];
    // std::find(first_begin, first_end, second) != first_end;

    auto first_begin = rowPtr[first];
    auto first_end   = rowPtr[first + 1] - 1;
    auto first_mid   = (first_begin + first_end) / 2;
    while(first_begin <= first_end)
    {
      if(colIdx[first_mid] == second)
      {
        return true;
      }
      else if(colIdx[first_mid] < second)
      {
        first_begin = first_mid + 1;
      }
      else
      {
        first_end = first_mid - 1;
      }
      first_mid = (first_begin + first_end) / 2;
    }
    return false;
  };

  for(int first = 0; first < numVertices; first++)
  {
    for(int i = rowPtr[first]; i < rowPtr[first + 1]; i++)
    {
      for(int j = i + 1; j < rowPtr[first + 1]; j++)
      {
        const auto second = colIdx[i];
        const auto third  = colIdx[j];
        if(intersect(second, third))
        {
          numTriangles++;
        }
      }
    }
  }
  return numTriangles / 3;
}

int main()
{
  std::vector<int> rowPtr      = { 0, 3, 5, 7, 10, 12, 14 };
  std::vector<int> colIdx      = { 1, 2, 3, 0, 2, 0, 1, 0, 4, 5, 3, 5, 3, 4 };
  const auto       numVertices = rowPtr.size() - 1;
  for(int i = 0; i < numVertices; i++)
  {
    std::sort(colIdx.begin() + rowPtr[i], colIdx.begin() + rowPtr[i + 1]);
  }
  // unweighted graph for simplicity
  auto triangles = bfs_tc(rowPtr, colIdx);
  std::cout << "number of trianlges: " << triangles << std::endl;
}